Entrypoint
The common entrypoint implements CommonModInitializer. It runs on both the client and the server, and every declaration (blocks, items, commands, network, game tests, and so on) must finish inside this method.
Change the CrystalGardenMod.java that initPolyMod renamed from the template to the code below. First, declare only the crystal item and the crystal block. The next pages fill in the rest.
package com.example.crystalgarden;
import dev.polymodloader.api.content.CreativeTab;
import dev.polymodloader.api.content.block.BlockDefinition;
import dev.polymodloader.api.content.block.BlockSound;
import dev.polymodloader.api.content.item.ItemDefinition;
import dev.polymodloader.api.content.item.ItemRarity;
import dev.polymodloader.api.lifecycle.CommonModInitializer;
import dev.polymodloader.api.lifecycle.ModContext;
import dev.polymodloader.api.resource.ResourceId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class CrystalGardenMod implements CommonModInitializer {
static final String MOD_ID = "crystal_garden";
static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
static final ResourceId CRYSTAL = ResourceId.of(MOD_ID, "crystal");
static final ResourceId CRYSTAL_BLOCK = ResourceId.of(MOD_ID, "crystal_block");
@Override
public void onInitializeCommon(ModContext mod) {
LOGGER.info("[{}] Planting Crystal Garden {}", MOD_ID, mod.modVersion());
mod.content()
.item(
"crystal",
ItemDefinition.builder()
.rarity(ItemRarity.UNCOMMON)
.creativeTab(CreativeTab.INGREDIENTS)
.build());
mod.content()
.block(
"crystal_block",
BlockDefinition.builder()
.strength(1.5f, 1.5f)
.requiresCorrectTool()
.sound(BlockSound.AMETHYST)
.lightLevel(6)
.item(ItemDefinition.builder()
.creativeTab(CreativeTab.BUILDING_BLOCKS)
.build())
.build());
}
}
ResourceId.of(MOD_ID, "crystal")iscrystal_garden:crystal. Other classes and tests find the item by this ID.- A block declared with
.item(...)also registers a block item with the same ID. worldCreateSaveTestinbuild.gradle.ktscan check the log line. Replace the template's check lines (Hello from …,Server started) with the single line[crystal_garden] Planting Crystal Garden 0.1.0.
A declaration made after the game closes the registries (for example, declaring an item inside an event listener) is a POLY-CONTENT-002 error. Commands, network, and game tests follow the same rule with POLY-COMMAND-002, POLY-NETWORK-002, and POLY-GAMETEST-002.
If an entrypoint throws an exception, Poly Mod Loader stops with POLY-ENTRYPOINT-003.
Entrypoint types
| Interface | poly.mod.json key | When it runs |
|---|---|---|
CommonModInitializer | common | In dependency order, on the main thread, before the game's main |
ClientModInitializer | client | After all common entrypoints, on the client only |
DedicatedServerModInitializer | server | After all common entrypoints, on the dedicated server only |
Between mods, dependencies run first. Ties are broken by mod ID order.
ModContext
You reach every API area through the ModContext the entrypoint receives.
| Method | Contents | Docs |
|---|---|---|
modId(), modVersion(), side() | Mod ID, version, running side (CLIENT / DEDICATED_SERVER) | — |
content() | Blocks, items, entities, effects, game rules, sounds, particles, and more | Blocks |
events() | Event listener registration | Events |
commands() | Commands | Commands and permissions |
network() | Payload channels | Networking and sync |
worldgen() | Biome features, code biomes, terrain generators | World generation |
resources() | Data and asset reload listeners | Resources and data |
permissions() | Permission nodes and providers | Commands and permissions |
gameTests() | In-game tests | In-game tests |
configDirectory() | The config/<mod id> settings folder | Operations |
onShutdown(description, task) | A task to run when the JVM shuts down | Operations |
client() | Key bindings, HUD, rendering (only in the client entrypoint) | Client basics |
Next step
In First block, you give this item and block their look.