Example mods
The examples/ folder in the Poly Mod Loader source holds five Poly Mod examples. All of them are verified in the real game. The Poly Mod Loader source is private for now, so this page describes what each example shows; the code the docs need is on the Native API pages.
To start a new mod, download the mod template, not an example. See Get the mod template.
At a glance
| Path | Mod ID | What it shows |
|---|---|---|
examples/crystal-garden | crystal_garden | The finished result of the Create your first Poly Mod tutorial. A growing block, stored data, commands and permissions, a join check, client drawing, game tests |
examples/minimal-native-mod | minimal_native_mod | The smallest Poly Mod. An entrypoint, server events, a shutdown task |
examples/custom-system-mod | custom_system_mod | System replacement (poly:game_brand) |
examples/transform-demo-mod | transform_demo_mod | Code transforms, call-site changes, ordering declarations, and access widening declared in poly.mod.json |
examples/native-showcase-mod | native_showcase | Every Native API area, with in-game tests |
crystal-garden
This is the mod you build in the tutorial. Unlike the other examples, it is a standalone project built the same way as a mod author would build it (the mod plugin dev.polymodloader.mod). A crystal sprout grows in 4 stages, and using a fully grown sprout gives you a crystal.
| File | Content |
|---|---|
CrystalGardenMod | Common entrypoint. Item and block declarations, entity data key, permission node, join check |
CrystalSprout | The stage block state, shape and brightness per state, a block entity that grows every tick, harvesting (writes entity data and world storage) |
GardenCommands | /garden stats, /garden grow <pos> (permission crystal_garden:grow) |
CrystalGardenClient | Join check reply, growth display above a sprout, harvest count HUD, key binding toggle_hud (default G) |
GardenTests | 4 in-game tests |
minimal-native-mod
The smallest Poly Mod. It adds no game content such as blocks or items. It only logs that the entrypoint ran.
| File | Content |
|---|---|
poly.mod.json | "minecraft": ["26.*"], common and client entrypoints, the poly dependency |
MinimalNativeMod | Common entrypoint. A greeting log, a shutdown task (onShutdown), ServerEvents.STARTED and STOPPING listeners |
MinimalNativeModClient | Client entrypoint. Only logs that it was called |
custom-system-mod
It replaces the poly:game_brand system so the brand that Minecraft reports becomes poly/example. It references no Minecraft classes.
| File | Content |
|---|---|
poly.mod.json | No entrypoints. Declares the provider in replacesSystems and requests the permission system.provider.replace |
ExampleBrandProvider | The poly:game_brand provider |
The client log shows [Poly Mod Loader] poly:game_brand reported 'poly/example' to Minecraft (CLIENT). How to declare this is in the poly.mod.json schema.
transform-demo-mod
It changes Minecraft classes with transforms and accessWidenings in poly.mod.json. The first rule works from the declaration alone, with no Java code. The second rule uses a small hook class, TickHooks.
| Rule | Target | Action | What it does |
|---|---|---|
| transform_demo_mod:storage_format_name | LevelStorageSource.getName()Ljava/lang/String; | replace_returned_string_constant | Changes the display storage format name "Anvil" to "Anvil (Poly Mod Loader transform demo)" |
| transform_demo_mod:tick_start_nanos | MinecraftServer.tickServer(Ljava/util/function/BooleanSupplier;)V | redirect_call, after: ["poly:server_tick_events"] | Replaces the first Util.getNanos() call with TickHooks.tickStartNanos(). It targets the same method as Poly Mod Loader's built-in start hook, so it declares an order |
| Access widening | MinecraftServer.tickCount:I | accessible | Makes a private field public |
- The failure policies are
disable_ruleandskip, so if the target changes, only that entry is turned off. - The permissions are
internal.bytecode.transform,internal.callsite.intercept, andinternal.member.access. minecraftis["26.2"]. It depends on game code of a specific version, so it names the exact version.
The log shows the following. From the second run on, the transform cache is used and from cache is added.
Transformed net/minecraft/world/level/storage/LevelStorageSource with [transform_demo_mod:storage_format_name]Transformed net/minecraft/server/MinecraftServer with [poly:server_brand, poly:server_tick_events, transform_demo_mod:tick_start_nanos, poly:server_stopping_event, poly:worldgen_features, access widening by transform_demo_mod][transform_demo_mod] tickServer start time comes from the mod hook; MinecraftServer.tickCount is public: true
native-showcase-mod
This example uses every area of the Native API in one mod. Poly Mod Loader uses it as the reference mod when it verifies the Native API in the real game. Its poly.mod.json has "minecraft": ["26.*"].
Classes
| Class | Area | Content |
|---|---|---|
NativeShowcaseMod | Common entrypoint | The glowing block glow_block (brightness 12, needs the right tool, gives spark when used), the item spark, the food star_fruit, commands, a network channel, a join-preparation exchange, events, world storage, the config file showcase.properties, the mod creative tab showcase, and calls to declarations in other classes |
MachineContent | Block state and block entities | machine, which faces the player, toggles powered when used, and counts ticks while on; and crate, a 27-slot inventory |
AdvancedContent | Advanced content | lamp with a color property and per-state brightness, grinder with a menu layout and a progress bar, spark_wand using the item data component charge, the projectile spark_bolt, and the advancement trigger used_wand |
CreatureContent | Mobs and gameplay | The mob golem_friend with a spawn egg, natural spawning, and riding; the status effect glowing_heart; the game rules golems_greet_players and spark_multiplier; the sound chime; damage and death events |
SeekGlowBlockGoal | AI goal | Walks toward a glow_block within 6 blocks |
VisualContent | Mob model | The flying mob wisp with a box model and keyframe animation, and the particle sparkle |
MovementContent | Shape and movement | The half-height block stone_step, the swimming mob minnow, and related game tests |
WorldContent | World generation | The biome glow_meadow, a terraced terrain generator used by the native_showcase:terraces dimension, and chunk load watching |
CodeWorldgenContent | Code world generation | The placed feature boulder, the density function waves of the native_showcase:waves dimension, the structure shrine, and related game tests |
InteractionContent | Event priorities and interaction events | warded_block, which protects itself and what stands on it with BlockEvents.BREAK (high priority), PLACE, PLACED, and the InteractionEvents, and 6 game tests that show each event cancels its action while the uncanceled action still works |
LifecycleContent | Lifecycle events | Server and overworld lifecycle log lines, a respawn counter in entity data copied by PlayerEvents.COPY, RESPAWNED, EntityEvents.JOINED_WORLD, and 2 game tests with a connected mock player |
TagContent | Tags | #native_showcase:warded (drives the warded block's protection), #native_showcase:sparkly, the warded block added to #minecraft:mineable/pickaxe, and 2 game tests |
OperationsContent | Data, sync, and operations | A data reload listener, the entity data visits and golem_mood (including version migration), the versioned world storage world_info synced with the client, the permission nodes place and secret with a permission provider, and a join check |
NativeShowcaseClient | Client entrypoint | Key binding, HUD layer, shader pipelines glow and pulse (texture and mod uniforms), the world drawing compass, grinder block entity drawing (a lamp model per state), the dynamic texture noise, a screen, camera view, the post-processing sepia, client events, and the "Sparkly" tooltip line for items in #native_showcase:sparkly |
ShowcaseScreen | Mod screen | A greeting text, a name input field, a close button |
ShowcaseGameTests | In-game tests | Content, world, entity, command, data, and permission tests |
Resources are in src/main/resources/assets/native_showcase/ (block states, models, textures, names, shaders, post-processing) and src/main/resources/data/ (loot tables, recipes, tags, the dimensions pocket, terraces and waves, advancements, damage types, world generation data).
Commands, keys, and channels
| Kind | Name | Behavior |
|---|---|---|
| Command | /showcase info | Tells you whether the block is registered |
| Command | /showcase add <a> <b> | Returns the sum of two integers as the command result |
| Command | /showcase place <pos> | Places a glow_block at that position. Needs the permission node place (default level 2) |
| Key binding | show_info (default K) | Shows Native Showcase: key binding works in the action bar |
| Payload channel | native_showcase:greetings | On join, the server sends a welcome greeting and the client replies with thanks |
| Join-preparation exchange | native_showcase:handshake | Before the player enters the world, the server asks for the client's showcase version. It rejects the connection if there is no reply or the reply does not start with showcase |
Testing in the game
Run the showcase's 52 in-game tests inside a world with /test runmultiple native_showcase:*. To write and run tests for your own mod, see In-game tests.