Developing on Mycel
Mycel ships as one universal jar for Fabric, Forge, and NeoForge alike, distributed through JitPack. Use a release tag (for example 1.1.0), a commit hash, or main-SNAPSHOT for bleeding edge. The pattern below is exactly how InstantXP and AutoBlockRefiller are built; both repos are small enough to read end to end.
Depending on Mycel
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
// Fabric (loom)
modImplementation 'com.github.MyCelium-GG:MyCel-Lib:1.1.0'
// Forge (ForgeGradle userdev)
// implementation 'com.github.MyCelium-GG:MyCel-Lib:1.1.0'
// NeoForge (ModDev)
// implementation 'com.github.MyCelium-GG:MyCel-Lib:1.1.0'
}
Minimal integration
Metadata, a config value, and an event subscription. File IO, loader events, and diagnostics come from Mycel:
public static final ModMetadata META =
ModMetadata.builder("mymod", "My Mod", "1.0.0").build();
public static final ConfigValue<Boolean> ENABLED;
public static final MycelConfig CONFIG;
public static void init() { // called from each loader entrypoint
Mycel.initialize();
Mycel.registerMod(META);
ConfigBuilder builder = Mycel.config(META);
ENABLED = builder.booleanValue("enabled", true, "Whether the feature runs.");
CONFIG = builder.build(); // loads config/mymod.json
MycelEvents.onPlayerJoin(event -> {
if (Mycel.isEnabled("mymod") && ENABLED.get()) {
PlayerUtil.sendMessage(event.player(), Component.literal("Hi!"));
}
});
}
More of the API
- More config types:
intValue(key, def, min, max, desc),longValue,doubleValue,stringValue,enumValue,stringListValue. Group withbuilder.category("tweaks")/builder.root(), version withschemaVersion+migrate, reload withCONFIG.reload()or/mycel reload mymod. - Scheduling:
MycelScheduler.runLater/runEveryon the server thread,runAsyncfor background IO. - Config screen:
Mycel.openConfigScreen(parent, "mymod")is server-safe (returns null on dedicated servers). Register it for the mod-list entry on Forge/NeoForge; on Fabric add a one-line ModMenu integration. - House rules: loader-independent code goes in
common(vanilla imports only); loader quirks stay in thin per-loader entrypoints using each loader's native event bus. No per-tick scans without a reason, no sync HTTP, no required background threads.
Project layout
common/ loader-independent mod code (no loader imports)
fabric/ Fabric entrypoint + fabric.mod.json
forge/ Forge entrypoint + mods.toml
neoforge/ NeoForge entrypoint + neoforge.mods.toml
buildSrc/ shared Gradle conventions
Building
You need JDK 25. Then:
./gradlew build # all loaders + tests
./gradlew :common:test # unit tests only
First builds download and process Minecraft (caches around a gigabyte, decompile takes a few minutes, peaks around 6-8 GB RAM); later builds are incremental. Finished jars land in fabric/build/libs, forge/build/libs, and neoforge/build/libs.
Example repos
- InstantXP - tick-driven collection, int config
- AutoBlockRefiller - event-driven refill with deferred check
- MyCel-Lib - the library itself, plus a join-greeting example mod proving the whole API