Create the project
Create it with one command (recommended)
Run initPolyMod in the template folder you unzipped (crystal-garden). It renames the mod ID, name, package, entrypoint class, and project name in place.
- Windows (PowerShell)
- macOS · Linux (bash)
.\gradlew.bat initPolyMod -PmodId=crystal_garden "-PmodName=Crystal Garden" "-PmodPackage=com.example.crystalgarden"
.\gradlew.bat build
./gradlew initPolyMod -PmodId=crystal_garden "-PmodName=Crystal Garden" "-PmodPackage=com.example.crystalgarden"
./gradlew build
If build succeeds, you are ready. You can skip Rename the template by hand below. initPolyMod works only on an unchanged copy of the template; to start over, unzip the template again. The properties and their defaults are in Mod development tools.
The generated project
crystal-garden/
├─ settings.gradle.kts project name, where Gradle finds Poly Mod Loader
├─ build.gradle.kts mod plugin dev.polymodloader.mod
├─ gradle.properties Minecraft version to run (optional)
├─ .run/runClient.run.xml IntelliJ run configuration
├─ src/main/java/com/example/crystalgarden/CrystalGardenMod.java entrypoint
└─ src/main/resources/poly.mod.json mod metadata
The template includes a ruby item and a ruby block as examples. The next pages replace them with the Crystal Garden code.
pluginManagement {
// -PpolyLocalSdk: use a local Poly Mod Loader build (./gradlew publishToMavenLocal and
// ./gradlew -p build-logic publishToMavenLocal in Poly Mod Loader) even for a version that is published.
val localFirst = providers.gradleProperty("polyLocalSdk").isPresent
repositories {
if (localFirst) mavenLocal()
// The Poly Mod Loader SDK: the dev.polymodloader.mod plugin and, through it, Poly Mod Loader itself.
maven("https://www.polymc.net/maven/") {
name = "Poly Mod Loader"
content { includeGroupByRegex("dev\\.polymodloader(\\..*)?") }
}
// A local Poly Mod Loader build of a version the SDK repository does not have.
if (!localFirst) mavenLocal()
gradlePluginPortal()
}
}
rootProject.name = "crystal-garden"
Gradle looks for the dev.polymodloader.mod plugin, and through it Poly Mod Loader itself, on the Poly Mod Loader website's Maven repository first (only the dev.polymodloader group), then in Maven Local, then on the Gradle Plugin Portal. It takes a version from the first repository that has it. -PpolyLocalSdk puts Maven Local first, for contributors who test a local Poly Mod Loader build (Get the mod template).
The first line of build.gradle.kts is the Poly Mod Loader mod plugin.
plugins {
id("dev.polymodloader.mod") version "0.2.0-beta.2"
}
group = "com.example"
version = "0.1.0"
The dev.polymodloader.mod plugin provides the following.
- A Java 25 toolchain
compileOnlydependencies: the Native API (poly-lifecycle-api) and SLF4J. Poly Mod Loader provides them at run time, so they do not go into the mod jarvalidatePolyModJson: checkspoly.mod.jsonwith the same validator Poly Mod Loader uses (part ofcheck)polyResourcesandgeneratePolyResources: generate the model, block state, loot, and name files for blocks and items at build timecheckPolyResources: finds mistakes in file names, JSON, and model and texture references before you start the game (part ofcheck)- Run and verification tasks:
runClient,runServer,gameTests,worldCreateSaveTest,clientWorldReloadTest,serverBootSmokeTest
Rename the template by hand
You can also rename the unzipped template yourself instead of running initPolyMod. Change the following four places.
| What to change | Example |
|---|---|
id, name, and entrypoints in poly.mod.json | "id": "crystal_garden" |
| Java package and classes | com.example.mymod.MyMod → com.example.crystalgarden.CrystalGardenMod |
| Resource folders | assets/my_mod/ → assets/crystal_garden/, data/crystal_garden/ |
settings.gradle.kts, build.gradle.kts | rootProject.name, group, the log line that worldCreateSaveTest checks |
Use only lowercase letters, digits, and underscores in a mod ID.
If a resource folder name differs from the mod ID, the game cannot find models, textures, or translations. If you see a purple and black checkered texture in game, check the folder names first.
Next step
Fill in poly.mod.json.