Skillshub minecraft-modding

install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/Jahrome907/minecraft-codex-skills/minecraft-modding" ~/.claude/skills/comeonoliver-skillshub-minecraft-modding && rm -rf "$T"
manifest: skills/Jahrome907/minecraft-codex-skills/minecraft-modding/SKILL.md
source content

Minecraft Modding Skill

Overview

This skill guides Codex through developing open-source Minecraft mods. Target platforms:

PlatformMC VersionJavaBuild System
NeoForge1.21.1 / 1.21.4 / 1.21.5Java 21Gradle + ModDevGradle
Fabric1.21.1 / 1.21.4Java 21Gradle + Fabric Loom
Architectury (multiloader)1.21.xJava 21Gradle + Architectury Loom

Always confirm the platform and Minecraft version from

gradle.properties
or
build.gradle
before writing any mod-specific code.

Routing Boundaries

  • 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
    ).

1. Identifying the Platform

# NeoForge project signature
grep -r "net.neoforged" 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:

  • NeoForge:
    src/main/resources/META-INF/neoforge.mods.toml
    , annotated
    @Mod
    main class
  • Fabric:
    src/main/resources/fabric.mod.json
    , class implementing
    ModInitializer
  • Architectury:
    common/
    ,
    fabric/
    ,
    neoforge/
    subprojects

2. Build & Test Commands

# 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


3. Project Layout (NeoForge)

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/

4. Project Layout (Fabric)

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

5. Core Concepts Cheatsheet

Sides

  • Physical client – the game client JAR (has rendering code)
  • Physical server – the dedicated server JAR (no rendering)
  • Logical client – the client thread (handles rendering, input)
  • Logical server – the server thread (handles world simulation)
  • Code decorated with
    @OnlyIn(Dist.CLIENT)
    (NeoForge) or
    @Environment(EnvType.CLIENT)
    (Fabric) must NEVER run on the server.

Registries

Everything in Minecraft lives in a registry. Always register objects; never construct them at field initializer time outside a registry call.

  • Blocks →
    Registry.BLOCK
  • Items →
    Registry.ITEM
  • Entity types →
    Registry.ENTITY_TYPE
  • Block entity types →
    Registry.BLOCK_ENTITY_TYPE
  • Menu types →
    Registry.MENU
    (NeoForge) /
    Registry.MENU_TYPE
    (Fabric)
  • Sound events →
    Registry.SOUND_EVENT
  • Biomes →
    Registry.BIOME

ResourceLocation / Identifier

Every registry entry needs a namespaced ID:

// NeoForge / vanilla Java
ResourceLocation id = ResourceLocation.fromNamespaceAndPath("mymod", "my_block");

// Fabric (same class, same API in 1.21)
Identifier id = Identifier.of("mymod", "my_block");

6. NeoForge Quick Patterns

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());
}

7. Fabric Quick Patterns

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);
    }
}

8. JSON Asset Templates

Always provide matching JSON assets for every registered block/item. Codex should generate or update these files alongside Java code.

See

references/common-patterns.md
for full JSON templates for:

  • Blockstate JSON
  • Block model JSON (cube, slab, stairs, fence, door, trapdoor, etc.)
  • Item model JSON
  • Loot table JSON
  • Recipe JSON (crafting_shaped, crafting_shapeless, smelting, blasting, stonecutting)
  • Language file (
    en_us.json
    ) entries
  • Tag JSON

9. Data Generation

Prefer 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.


10. Common Tasks Checklist

When adding a new block:

  • Block
    subclass (or use vanilla Block with properties)
  • Register in
    ModBlocks.BLOCKS
    /
    Registries.BLOCK
  • Register
    BlockItem
    in
    ModItems.ITEMS
    /
    Registries.ITEM
  • Blockstate JSON →
    assets/<modid>/blockstates/<name>.json
  • Block model JSON →
    assets/<modid>/models/block/<name>.json
  • Item model JSON →
    assets/<modid>/models/item/<name>.json
    (or inherits from block)
  • Texture PNG →
    assets/<modid>/textures/block/<name>.png
  • Loot table JSON →
    data/<modid>/loot_table/blocks/<name>.json
  • Language entry in
    en_us.json
  • Mine-with-correct-tool tag if hardness > 0

When adding a new item:

  • Item
    subclass (or use
    new Item(properties)
    )
  • Register in
    ModItems
    /
    Registries.ITEM
  • Item model JSON
  • Texture PNG
  • Language entry
  • Creative tab registration (NeoForge:
    BuildCreativeModeTabContentsEvent
    ; Fabric:
    ItemGroupEvents
    )
  • Recipe JSON if craftable

When adding a new entity:

  • Entity class (extends appropriate base:
    Mob
    ,
    Animal
    ,
    TamableAnimal
    , etc.)
  • EntityType
    registration
  • Renderer class (
    @OnlyIn(Dist.CLIENT)
    )
  • Model class (
    @OnlyIn(Dist.CLIENT)
    )
  • Register renderer in
    EntityRenderersEvent.RegisterRenderers
    (NeoForge) or
    EntityModelLayerRegistry
    (Fabric)
  • Spawn egg item (optional)
  • Spawn rules / biome modifier

11. Open-Source Conventions

  • License: MIT or LGPL-3.0 — include
    LICENSE
    file and
    SPDX-License-Identifier
    header
  • Versioning:
    {mod_version}+{mc_version}
    (e.g.,
    2.0.0+1.21.1
    )
  • Changelog: Keep
    CHANGELOG.md
    up to date with semver notes
  • Publishing: Use
    gradle-modrinth
    or
    curseforgegradle
    plugins for CurseForge / Modrinth
  • CI: GitHub Actions with
    ./gradlew build
    and
    ./gradlew runGameTestServer
  • PR conventions: Keep PRs scoped to a single feature; include asset files with Java changes

12. References