Full-stack Minecraft mod development skill for NeoForge (1.21+), Fabric (1.21+), and legacy Forge 1.20.1. Scaffolds new mods, adds custom blocks, items, entities, recipes, commands, GUIs, dimensions, and data generation. Knows NeoForge DeferredRegister + event-bus patterns, Forge 1.20.1 MDK/FMLJavaModLoadingContext patterns, and Fabric Registry + ModInitializer patterns. Use when the user asks to create a Minecraft mod, add a feature to an existing mod, fix a mod bug, generate JSON assets/data, support Forge 1.20.1, or migrate between modding platforms. Prefer NeoForge unless the user specifies Fabric, Forge 1.20.1, or Multiloader.
npx skills add https://github.com/Jahrome907/minecraft-agent-skills --skill minecraft-modding
This skill guides Codex through developing open-source Minecraft mods.
Target platforms:
| Platform | MC Version | Java | Build System |
|---|---|---|---|
| NeoForge | 1.21.x with 1.21.11 examples | Java 21 | Gradle + ModDevGradle |
| Forge | 1.20.1 legacy lane | Java 17 | Gradle + ForgeGradle 6 |
| Fabric | 1.21.x with 1.21.11 examples | Java 21 | Gradle + Fabric Loom |
| Architectury (multiloader) | 1.21.x | Java 21 | Gradle + Architectury Loom |
Always confirm the platform and Minecraft version from gradle.properties or build.gradle
before writing any mod-specific code.
Use when: the task is Java/Kotlin mod code, registry/event work, networking, datagen wiring, and loader APIs.Do not use when: the task is command-only vanilla logic (minecraft-commands-scripting) or pure datapacks (minecraft-datapack).Do not use when: the task targets Paper/Bukkit plugins (minecraft-plugin-dev).# NeoForge project signature
grep -r "net.neoforged" gradle.properties build.gradle settings.gradle 2>/dev/null | head -5
# Forge 1.20.1 project signature
grep -r "net.minecraftforge" gradle.properties build.gradle settings.gradle 2>/dev/null | head -5
# Fabric project signature
grep -r "fabric" gradle.properties build.gradle settings.gradle 2>/dev/null | head -5
# Read mod ID and version
cat gradle.properties
Key files per platform:
src/main/resources/META-INF/neoforge.mods.toml, annotated @Mod main classsrc/main/resources/META-INF/mods.toml, net.minecraftforge:forge dependencysrc/main/resources/fabric.mod.json, class implementing ModInitializercommon/, fabric/, neoforge/ subprojects# Build the mod jar
./gradlew build
# Run the Minecraft client to test
./gradlew runClient
# Run a dedicated server to test
./gradlew runServer
# Run game tests (NeoForge JUnit-style game tests)
./gradlew runGameTestServer
# Run data generation (generates JSON assets automatically)
./gradlew runData
# Clean build cache
./gradlew clean
# Check for dependency updates (optional)
./gradlew dependencyUpdates
After ./gradlew build, the mod jar is at:
build/libs/<mod_id>-<version>.jar
src/
main/
java/<groupId>/<modid>/
MyMod.java ← @Mod entry point
block/
ModBlocks.java ← DeferredRegister<Block>
MyCustomBlock.java
item/
ModItems.java ← DeferredRegister<Item>
entity/
ModEntities.java ← DeferredRegister<EntityType<?>>
menu/ ← custom GUI containers
recipe/
worldgen/
datagen/
ModDataGen.java ← GatherDataEvent handler
providers/
resources/
META-INF/
neoforge.mods.toml ← mod metadata (renamed from mods.toml in NeoForge 1.20.5+)
assets/<modid>/
blockstates/ ← JSON blockstate definitions
models/
block/ ← block model JSON
item/ ← item model JSON
textures/
block/ ← 16×16 PNG textures
item/
lang/
en_us.json ← translation strings
data/<modid>/
recipes/ ← crafting recipe JSON
loot_table/
blocks/ ← per-block loot table JSON
tags/
blocks/
items/
Use this layout only when minecraft_version=1.20.1 and the project depends on
net.minecraftforge:forge. Forge 1.20.1 is not NeoForge: keep mods.toml,
net.minecraftforge.* imports, Java 17, and ForgeGradle 6 patterns.
src/
main/
java/<groupId>/<modid>/
MyMod.java <- @Mod entry point
block/
ModBlocks.java <- DeferredRegister<Block>
item/
ModItems.java <- DeferredRegister<Item>
datagen/
ModDataGen.java <- GatherDataEvent handler
resources/
META-INF/
mods.toml <- Forge metadata
assets/<modid>/ <- client assets
data/<modid>/ <- server data using 1.20.1 paths
See references/forge-1.20.1-api.md before editing Forge 1.20.1 projects.
src/
main/
java/<groupId>/<modid>/
MyMod.java ← implements ModInitializer
client/
MyModClient.java ← implements ClientModInitializer
block/
item/
mixin/ ← Mixin classes
resources/
fabric.mod.json
assets/<modid>/ ← same as NeoForge
data/<modid>/ ← same as NeoForge
<modid>.mixins.json ← mixin configuration
@OnlyIn(Dist.CLIENT) (NeoForge) or @Environment(EnvType.CLIENT) (Fabric)must NEVER run on the server.
Everything in Minecraft lives in a registry. Always register objects; never
construct them at field initializer time outside a registry call. Use the
mapping-appropriate registry constants for the loader you are editing:
| Type | NeoForge / Mojang mappings | Fabric / Yarn mappings |
|------|-----------------------------|-------------------------|
| Blocks | BuiltInRegistries.BLOCK | Registries.BLOCK |
| Items | BuiltInRegistries.ITEM | Registries.ITEM |
| Entity types | BuiltInRegistries.ENTITY_TYPE | Registries.ENTITY_TYPE |
| Block entity types | BuiltInRegistries.BLOCK_ENTITY_TYPE | Registries.BLOCK_ENTITY_TYPE |
| Menu / screen-handler types | BuiltInRegistries.MENU | Registries.SCREEN_HANDLER |
| Sound events | BuiltInRegistries.SOUND_EVENT | Registries.SOUND_EVENT |
| Biomes | Registries.BIOME registry keys | RegistryKeys.BIOME registry keys |
Do not copy older Registry.BLOCK / Registry.ITEM constants into 1.21.x code;
those names are stale for the examples in this skill.
Every registry entry needs a namespaced ID:
// NeoForge / vanilla Java
ResourceLocation id = ResourceLocation.fromNamespaceAndPath("mymod", "my_block");
// Fabric with Yarn mappings
Identifier id = Identifier.of("mymod", "my_block");
See full patterns in references/neoforge-api.md.
// Main mod class
@Mod(MyMod.MOD_ID)
public class MyMod {
public static final String MOD_ID = "mymod";
public MyMod(IEventBus modEventBus) {
ModBlocks.BLOCKS.register(modEventBus);
ModItems.ITEMS.register(modEventBus);
modEventBus.addListener(this::commonSetup);
}
private void commonSetup(FMLCommonSetupEvent event) {
// runs after all mods are registered
}
}
// Block registration
public class ModBlocks {
public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(BuiltInRegistries.BLOCK, MyMod.MOD_ID);
public static final DeferredBlock<Block> MY_BLOCK =
BLOCKS.registerSimpleBlock("my_block",
BlockBehaviour.Properties.of()
.mapColor(MapColor.STONE)
.strength(1.5f, 6.0f)
.sound(SoundType.STONE)
.requiresCorrectToolForDrops());
}
See full patterns in references/forge-1.20.1-api.md.
// Main mod class
@Mod(MyMod.MOD_ID)
public class MyMod {
public static final String MOD_ID = "mymod";
public MyMod(FMLJavaModLoadingContext context) {
IEventBus modEventBus = context.getModEventBus();
ModBlocks.BLOCKS.register(modEventBus);
ModItems.ITEMS.register(modEventBus);
modEventBus.addListener(this::commonSetup);
MinecraftForge.EVENT_BUS.register(this);
}
private void commonSetup(FMLCommonSetupEvent event) {
// runs after registries are prepared
}
}
// Block registration
public class ModBlocks {
public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(ForgeRegistries.BLOCKS, MyMod.MOD_ID);
public static final RegistryObject<Block> MY_BLOCK =
BLOCKS.register("my_block", () -> new Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.STONE)
.strength(1.5f, 6.0f)
.sound(SoundType.STONE)
.requiresCorrectToolForDrops()));
}
See full patterns in references/fabric-api.md.
// Main mod class
public class MyMod implements ModInitializer {
public static final String MOD_ID = "mymod";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@Override
public void onInitialize() {
ModBlocks.register();
ModItems.register();
}
}
// Block registration
public class ModBlocks {
public static final Block MY_BLOCK = new Block(
AbstractBlock.Settings.create()
.mapColor(MapColor.STONE)
.strength(1.5f, 6.0f)
.sounds(BlockSoundGroup.STONE)
.requiresTool()
);
public static void register() {
Registry.register(Registries.BLOCK,
Identifier.of(MyMod.MOD_ID, "my_block"), MY_BLOCK);
}
}
Always provide matching JSON assets for every registered block/item.
Codex should generate or update these files alongside Java code.
For Forge 1.20.1, check references/forge-1.20.1-api.md for legacy server-data
directory names before creating loot tables or tags.
See references/common-patterns.md for full JSON templates for:
en_us.json) entriesPrefer data generation over hand-authored JSON for maintainability.
// NeoForge – register data gen providers in GatherDataEvent
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
DataGenerator gen = event.getGenerator();
PackOutput output = gen.getPackOutput();
ExistingFileHelper helper = event.getExistingFileHelper();
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
gen.addProvider(event.includeClient(), new ModBlockStateProvider(output, helper));
gen.addProvider(event.includeClient(), new ModItemModelProvider(output, helper));
gen.addProvider(event.includeServer(), new ModRecipeProvider(output, lookupProvider));
gen.addProvider(event.includeServer(), new ModLootTableProvider(output, lookupProvider));
gen.addProvider(event.includeServer(), new ModBlockTagsProvider(output, lookupProvider, helper));
}
Run data generation with ./gradlew runData, then commit the generated files.
For Forge 1.20.1, use the mod-event-bus registration, GatherDataEvent
signature, provider classes, and legacy output paths from
references/forge-1.20.1-api.md.
When adding a new block:
Block subclass (or use vanilla Block with properties)ModBlocks.BLOCKS / Registries.BLOCKBlockItem in ModItems.ITEMS / Registries.ITEMassets/<modid>/blockstates/<name>.jsonassets/<modid>/models/block/<name>.jsonassets/<modid>/models/item/<name>.json (or inherits from block)assets/<modid>/textures/block/<name>.pngdata/<modid>/loot_table/blocks/<name>.json; Forge 1.20.1: data/<modid>/loot_tables/blocks/<name>.jsondata/<modid>/tags/block/ and tags/item/; Forge 1.20.1: data/<modid>/tags/blocks/ and tags/items/en_us.jsonWhen adding a new item:
Item subclass (or use new Item(properties))ModItems / Registries.ITEMBuildCreativeModeTabContentsEvent; Fabric: ItemGroupEvents)When adding a new entity:
Mob, Animal, TamableAnimal, etc.)EntityType registration@OnlyIn(Dist.CLIENT))@OnlyIn(Dist.CLIENT))EntityRenderersEvent.RegisterRenderers (NeoForge) orEntityModelLayerRegistry (Fabric)
LICENSE file and SPDX-License-Identifier header{mod_version}+{mc_version} (e.g., 2.0.0+1.21.11)CHANGELOG.md up to date with semver notesgradle-modrinth or curseforgegradle plugins for CurseForge / Modrinth./gradlew build and ./gradlew runGameTestServer./references/neoforge-api.md./references/forge-1.20.1-api.md./references/fabric-api.md./references/common-patterns.mdGuide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take jahrome907/minecraft-modding from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.