Skip to main content
Version: Minecraft 26.2

Mod Development Tools

Gradle handles three tasks that you would otherwise repeat every time you make a mod.

ToolWhat it doesCommand
initPolyModTurns an unzipped copy of the mod template into a new mod: replaces the mod ID, package, and class names everywhereinitPolyMod -PmodId=… in the unzipped template
polyResourcesAt build time, generates the JSON you used to write by hand for each block and item (model, block state, item definition, loot, name, tool tag)One line in build.gradle.kts
checkPolyResourcesFinds uppercase file names, broken JSON, missing models and textures, and missing namespaces before you start the gameIncluded in build and check

Create a new mod: initPolyMod​

Run it in the folder of an unzipped mod template (Get the mod template). Only the mod ID is required.

.\gradlew.bat initPolyMod -PmodId=ruby_mod "-PmodName=Ruby Mod" "-PmodPackage=io.github.you.ruby"
.\gradlew.bat build
PropertyDefaultExample
modId (required)—ruby_mod (starts with a lowercase letter; 2 to 64 lowercase letters, digits, or _)
modNameThe mod ID with each word capitalizedRuby Mod
modPackagecom.example.<mod ID without underscores>io.github.you.ruby

It changes, in place: poly.mod.json (ID, name, entrypoint), the entrypoint class (RubyMod) and its package folder, the resource folders (assets/my_mod/ → assets/ruby_mod/), the project name in settings.gradle.kts, the group and the log lines to check in build.gradle.kts, and the IntelliJ run configuration. It does not rename the folder itself; rename it yourself if you like. It runs only on an unchanged copy of the template, and if a renamed file would overwrite an existing one, it changes nothing.

Contributors with the Poly Mod Loader source, which is private for now, can also run newPolyMod with the same properties there. It copies the template into a new folder next to the source (or -PmodDir=<folder>) and renames it the same way.

Generate resource files: polyResources​

Write the names of the blocks and items you registered in code into build.gradle.kts. The build then generates resource files in the same format as vanilla.

build.gradle.kts
polyResources {
item("ruby") // flat item that uses textures/item/ruby.png
block("ruby_block") { minedWith = "pickaxe" } // cube block that uses textures/block/ruby_block.png
block("ruby_lamp") {
displayName = "Ruby Lamp"
texture = "minecraft:block/redstone_lamp_on"
dropsSelf = false
}
}
DeclarationGenerated files
item("ruby")assets/<mod>/items/ruby.json, assets/<mod>/models/item/ruby.json, and item.<mod>.ruby in lang/en_us.json
block("ruby_block")blockstates/ruby_block.json, models/block/ruby_block.json (cube_all), items/ruby_block.json, data/<mod>/loot_table/blocks/ruby_block.json (drops itself), and block.<mod>.ruby_block in lang/en_us.json
minedWith = "pickaxe"Adds the block to data/minecraft/tags/block/mineable/pickaxe.json ("replace": false)
SettingMeaningDefault
textureTexture ID. Without a namespace, it is the mod's own (block/red → <mod>:block/red)<mod>:item/<name>, <mod>:block/<name>
displayNameEnglish nameThe name with each word capitalized (ruby_block → Ruby Block)
minedWith (block)pickaxe, axe, shovel, hoeNone
dropsSelf (block)Whether the block drops itself when brokentrue

Rules:

  • Files you write by hand win. If src/main/resources has a file at the same path, the tool does not generate that file. For a block with a different shape, such as stairs, you only need to write that one file yourself.
  • lang/en_us.json and tool tags are merged. Entries you wrote stay as they are, values included, and only missing names are added. You write other language files, such as Korean, yourself.
  • It does not create texture PNGs. Draw them yourself and put them under textures/.
  • Generated files are in build/generated/poly-resources/main and go into the jar. Nothing is written to the source folder.

Find mistakes before you start the game: checkPolyResources​

build (check) validates all the resources that go into the jar (hand-written and generated), collects every problem, shows them, and then fails. The result is also saved in build/reports/poly/resource-problems.txt.

2 problems in the mod's resources (src/main/resources and polyResources):
POLY-RESOURCE-004 assets/ruby_mod/textures/item/Ruby.png: Minecraft only loads resource paths made of lowercase a-z, 0-9, _ . - and /, and skips this file; rename it to assets/ruby_mod/textures/item/ruby.png
POLY-RESOURCE-007 assets/ruby_mod/models/item/ruby.json: texture "item/ruby" has no namespace, so the game looks for minecraft:item/ruby; write "ruby_mod:item/ruby" for this mod's file
CodeWhat it finds
POLY-RESOURCE-004A file path the game skips (uppercase letters, spaces, and so on)
POLY-RESOURCE-005JSON with a syntax error (trailing comma, missing quote). It gives the line and column
POLY-RESOURCE-006A model file that an item definition, block state, or model parent points to does not exist
POLY-RESOURCE-007A texture PNG that a model points to does not exist
POLY-RESOURCE-008A translation file value is not a string
POLY-RESOURCE-009A polyResources declaration error (invalid name, texture, or tool; the same name twice)

Scope of the check: it verifies only references inside namespaces for which the mod has an assets/<namespace> folder. Files in minecraft: and in other mods are not here, so it does not check them. A reference written without a namespace (item/ruby) means minecraft:, so if the same path exists on the mod's side, the tool reports that you left out the namespace. References that depend on code registration, such as item IDs in recipes and loot, can be checked only in the game.

Next step​

See code declarations and resources together in Make your first block.

Buy me a coffee