-
Notifications
You must be signed in to change notification settings - Fork 0
Building from Source
JDK 21. That's it — Gradle wrapper handles everything else.
./gradlew buildThe remapped mod jar lands in build/libs/.
The JUnit suite runs as part of build, so a failing test fails the build. That is deliberate — there is no green build with red tests.
./gradlew test # unit tests only
./gradlew runServer # headless dev server
./gradlew runClient # dev clientrunClient and runServer use run/ as their game directory, so dev configs land in run/config/mcmmo/ and dev worlds in run/saves/.
| Path | What's in it |
|---|---|
src/main/java/com/gmail/nossr50/ |
The mod. Ported mcMMO code keeps its original package structure. |
src/main/java/com/gmail/nossr50/fabric/ |
Fabric-specific entry point, listeners, platform adapters. |
src/main/resources/ |
Shipped YAML configs, mixin manifests, locale. |
src/test/java/ |
The JUnit suite. |
legacy/ |
The vendored upstream Bukkit tree, kept in-repo for reference during porting. Not compiled. |
plans/new-skills/ |
Design docs for the Pass-2 and future skills. |
scripts/ |
Dev helpers, including a javap wrapper over the Loom-cached yarn jar. |
PLAYTEST_G.md |
The in-game verification plan. |
A few conventions worth knowing before you send a patch.
Skill logic is kept free of net.minecraft types wherever possible, with Minecraft-typed glue in a thin layer around it. This is what lets most of the suite run as plain JUnit without a game bootstrap. If you're adding a mechanic, put the arithmetic in an MC-free class and the block/entity access in the listener.
platform/ wraps Minecraft types (players, items, blocks) behind final wrapper classes. Mockito 5 mocks final classes out of the box, so these are mockable in MC-free tests.
Some behaviour needs a mixin because Fabric has no event for it. Two hard-won rules:
-
An unresolvable
@Sliceis silently dropped, not raised — and the injector then binds everywhere in the method.defaultRequire=1will not catch this, becauserequireis a minimum. Always addallow = Nto a slice-anchored injector. -
assertDoesNotThrow(Class.forName(...))proves nothing for a class the test harness already loads. Assert a structural marker instead — an@Uniquefield, or the handler method ingetDeclaredMethods().
PrimarySkillType.name() is the on-disk save key and the milestone advancement filename. Renaming a constant silently orphans player data — the profile loader falls back to the starting level and the plaque simply stops firing, with no error.
Renames go through util/skills/SkillRenames. It costs one line there instead of a bug report.
SkillTools resolves a sub-skill's parent by matching the enum name up to the first _ against the primary skill names. So PARKOUR_SNOW_WALKER gates on Parkour, and UNARMORED_IRON_SKIN vs UNARMED_IRON_GRIP resolve to different skills — the match is equalsIgnoreCase on the whole prefix, not startsWith, so those two can't collide.
A rename would silently re-gate a sub-skill. Be careful.
The suite is ~970 cases and covers the MC-free cores directly plus a fabric-loader-junit harness for registry-backed tests.
./gradlew testFor registry-dependent tests, call McTestRegistries.bootstrap() in @BeforeAll.
Beyond unit tests, a change isn't done until it boots. ./gradlew runServer and confirm Done ( in the log with zero exceptions and zero mixin failures. A headless boot catches a surprising amount — a derived index logged at INFO proves a whole config scan ran, without needing a client.
Built and published automatically by .github/workflows/release.yml on every push to master or an mc/** branch, keeping one "latest" release per Minecraft line. Versioning uses the run number.
Issues and PRs welcome. Two things that make a PR much easier to take:
- Tests. New mechanics need unit coverage; bug fixes need a test that fails without the fix.
-
Say what you observed, not what you expected. "Seems fine" isn't a verification — a
/mcstatsdelta, a message on screen, or a block that changed is.
Balance feedback on the six new skills is especially wanted right now. Their XP rates and reference speeds are starting estimates, not measured numbers — see PLAYTEST_G.md.
mcMMO-SP — a single-player Fabric port of mcMMO by nossr50 and the mcMMO team. Licensed GPL-3.0-only.
Getting started
Gameplay
Reference
Development