-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Setup
How to build PlayerMob from source and how to depend on it from your own mod.
Prerequisites: JDK 21. The build pins the Java toolchain to 21 (Gradle will auto-provision a JDK 21 if you don't have one). The Fabric mixin transformer on 1.21.1 cannot read class files from JDK 23+, so 21 is mandatory.
git clone https://github.com/bh679/playermob-mc.git
cd playermob-mc
./gradlew build| Task | What it does |
|---|---|
./gradlew build |
Compile + package all three loader jars |
./gradlew :common:test |
Run the JUnit tests in common/
|
./gradlew fabric:runClient |
Launch a dev Fabric client with the mod loaded |
./gradlew neoforge:runClient |
Launch a dev NeoForge client |
./gradlew forge:runClient |
Launch a dev Forge client — currently blocked, see below |
./gradlew --stop |
Stop the Gradle daemon if a dev client hangs |
Built jars land in:
fabric/build/libs/playermob-fabric-<version>.jar
forge/build/libs/playermob-forge-<version>.jar
neoforge/build/libs/playermob-neoforge-<version>.jar
Forge
runClientcaveat.forge:runClientis blocked by an upstream Architectury Loom 1.13 + Forge 1.21.1 JPMS conflict (architectury-loom#284). The Forge production jar still builds and is verified by dropping it into a real Forge 1.21.1 install. Develop against Fabric and/or NeoForge dev clients.
PlayerMob is an Architectury multi-loader project.
Almost all logic lives in common/; each loader module is a thin entrypoint.
common/ Shared code — entity, AI goals, personality, skins, menus.
References only vanilla + the Fabric loader's mixin/annotation deps.
fabric/ Fabric entrypoint + client.
forge/ Forge entrypoint + client.
neoforge/ NeoForge entrypoint + client + the optional Dungeon Train integration.
Package root: games.brennan.playermob. See Architecture Overview for why
the split looks the way it does (short version: the Architectury API runtime
dropped Forge for 1.21, so registration is done per-loader with native APIs).
PlayerMob does not publish to a public Maven repository today. There are three
realistic ways to get its API on your compile classpath. In every case the
dependency is compileOnly / modCompileOnly at compile time plus a declared
mod dependency at runtime — you never bundle PlayerMob into your jar.
PlayerMob's releases publish per-loader to Modrinth. You can pull the published jar straight off the Modrinth Maven, exactly the way this repo consumes Dungeon Train (see Soft-Dependency Integrations):
repositories {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content { includeGroup "maven.modrinth" }
}
}
dependencies {
// <slug> = PlayerMob's Modrinth project slug (from its Modrinth page);
// <version> = the Modrinth version_number for your loader + MC 1.21.1.
modCompileOnly("maven.modrinth:<slug>:<version>") { transitive = false }
}Replace
<slug>and<version>with the real values from PlayerMob's Modrinth page — they aren't hard-coded in this repo, so this wiki won't guess them.
Each module publishes to a local file Maven at repo/ under the project root. From a
clone:
./gradlew publish # writes artifacts into ./repoThis produces games.brennan.playermob:playermob-common,
:playermob-fabric, :playermob-forge, and :playermob-neoforge (all at the
current mod_version). Point your build at that repo/ directory:
repositories {
maven { url "file:///absolute/path/to/playermob-mc/repo" }
}
dependencies {
compileOnly "games.brennan.playermob:playermob-common:0.15.0"
}For a quick spike, drop a built playermob-<loader>-<version>.jar into your project
and reference it with compileOnly files("libs/playermob-fabric-0.15.0.jar") (or your
loader's modCompileOnly/compileOnly equivalent).
So your mod loads after PlayerMob (and optionally requires it), declare it in your
loader metadata. PlayerMob's mod id is playermob.
Fabric — fabric.mod.json:
"depends": { "playermob": "*" }
// ...or, for an optional integration:
"suggests": { "playermob": "*" }NeoForge — neoforge.mods.toml:
[[dependencies.yourmodid]]
modId = "playermob"
type = "optional" # or "required"
versionRange = "[0.15.0,)"
ordering = "AFTER"
side = "BOTH"Forge — mods.toml:
[[dependencies.yourmodid]]
modId = "playermob"
mandatory = false # true = hard requirement
versionRange = "[0.15.0,)"
ordering = "AFTER"
side = "BOTH"For an optional integration (your mod works with or without PlayerMob), keep the
dependency compileOnly and gate your PlayerMob-touching code behind a
loaded-check — see the Soft-Dependency Integrations recipe.
PlayerMob ships through a strict review workflow (plan → test → merge gates).
Any change touching entity registration, the goal selector, the renderer, the spawn
egg, or the shared mixin config must be verified on Fabric and NeoForge dev
clients (Forge gets a production-jar smoke test). See
CLAUDE.md for the full
contributor process.
Getting started
No-code (datapacks)
Java API
Patterns