Files
custom_ore_gem/CLAUDE.md
2026-02-03 09:23:25 +01:00

12 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Custom Ore Gem is a Minecraft NeoForge 1.21.1 mod (mod ID: custom_ore_gen) that modifies ore distribution and adds Diamond Shard-tier tools and armor. This is an MCreator project - code in src/main/java is partially regenerated on each build.

Note: This mod replaces vanilla ore distribution with custom biome-based ore generation. For full functionality, it's recommended to use with KubeJS to remove vanilla ores (manual setup required).

Build Commands

# Build the mod (generates .jar in build/libs/)
./gradlew build

# Run client for testing
./gradlew runClient

# Run server for testing
./gradlew runServer

# Clean build artifacts
./gradlew clean

# Generate resources (data generation for assets/resources)
./gradlew runData

The built JAR is named custom_ore_gen-{version}.jar and appears in build/libs/.

Architecture

MCreator Workflow

This project uses MCreator. Files marked with MCreator note: This file will be REGENERATED on each build. at the top will be completely overwritten on each build. These include:

  • src/main/java/net/mcreator/customoregen/init/CustomOreGenModBlocks.java
  • src/main/java/net/mcreator/customoregen/init/CustomOreGenModItems.java
  • src/main/java/net/mcreator/customoregen/init/CustomOreGenModTabs.java

Protected User Code Blocks: Only CustomOreGenModItems.java contains protected user code blocks:

// Start of user code block custom items
// End of user code block custom items

Always preserve code between these markers when editing. All custom items (Ore Biome Finder, Shard Diamond armor, Paxel) are registered in this section.

Package Structure

net.mcreator.customoregen/
├── CustomOreGenMod.java          # Main mod class, registers event bus
├── OresCommand.java              # /ores command implementation
├── ShardDiamondArmorMaterial.java # Armor material class for Shard Diamond armor
├── block/                        # Ore block classes (17 blocks)
├── item/                         # Items (Diamond Shard, tools, armor, Paxel, OreBiomeFinder)
├── config/                       # NeoForge configuration system (ModConfigs.java)
├── event/                        # Event handlers (OreBreakEventHandler, EnchantabilityFix)
├── procedures/                   # Game logic (ConfigurableOreDropsProcedure, OreexperienceProcedure)
└── init/
    ├── CustomOreGenModBlocks.java  # Block registry (deferred register)
    ├── CustomOreGenModItems.java   # Item registry (REGENERATED)
    └── CustomOreGenModTabs.java    # Creative tabs registry

Ore Generation System

The mod uses NeoForge biome modifiers to distribute ores based on biome temperature tags. The architecture:

  1. Biome Tags (src/main/resources/data/custom_ore_gen/tags/worldgen/biome/):

    • cold_biomes.json - Cold biomes (lapis, concentrated diamond)
    • hot_biomes.json - Hot biomes (pure gold, copper, redstone)
    • mountain_biomes.json - Mountain biomes (high emerald)
    • rare_biomes.json - Rare biomes (lower emerald)
    • tempered_biomes.json - Temperate biomes (iron, concentrated coal)
    • BOP biomes are included with "required": false for optional compatibility
  2. Biome Modifiers (src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/):

    • Each ore has a JSON file linking it to biome tags
    • Special case: deepslatesharddiamondore_biome_modifier.json uses "type": "forge:any" for all biomes
    • JSON Structure:
      {
        "type": "neoforge:add_features",
        "biomes": "custom_ore_gen:cold_biomes",  // or {"type": "forge:any"} for all biomes
        "features": "custom_ore_gen:deepslatesharddiamondore",
        "step": "underground_ores"
      }
      
  3. Worldgen Features (src/main/resources/data/custom_ore_gen/worldgen/):

    • configured_feature/ - Defines ore vein size and height range
    • placed_feature/ - Places the feature in the world with vertical anchors

Diamond Shard Progression Tier

Diamond Shards are an intermediate tier between Iron and Diamond:

  • Items: Diamond Shard (diamondshard) - craft 9 shards into 1 diamond
  • Tools: Pickaxe, Shovel, Axe (200 durability), Paxel (1000 durability, combines all three)
  • Armor: Helmet (3), Chestplate (7), Leggings (5), Boots (2) - Total 17 protection, 1060 durability
  • Repair: All Diamond Shard equipment uses Diamond Shards

Configuration System

Located in src/main/java/net/mcreator/customoregen/config/:

  • ModConfigs.java - NeoForge configuration with 4 nested config classes: OreGenConfig, ToolStatsConfig, DropsConfig, FeatureToggleConfig
  • ConfigHelper.java - Utility class for accessing config values
  • Generated config file: config/custom_ore_gen-common.toml (created on first run)

Current Implementation Status:

  • Ore Drops: Fully implemented via OreBreakEventHandler.java which listens to BlockEvent.BreakEvent and calls ConfigurableOreDropsProcedure.execute() for all custom ores
  • ⚠️ Tool Stats: Config classes exist in ModConfigs.java, but tools currently have hardcoded values (e.g., SharddiamondpickaxeItem.java:18 has return 200 for durability). Config reading not yet implemented.
  • ⚠️ Feature Toggles: Defined in FeatureToggleConfig but not yet wired to block/item registration conditional logic
  • ⚠️ Ore Generation: Config values exist but worldgen JSON files still use hardcoded values
  • ⚠️ Enchantability: EnchantabilityFix.java exists but is commented out - enchantment values not yet applied to items

Ore Biome Finder

The OreBiomeFinderItem (item/OreBiomeFinderItem.java) and /ores command (OresCommand.java) detect which mod tags apply to the current biome and list findable ores.

Implementation Details:

  • Uses TagKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "...")) to define biome tags
  • Checks level.getBiome(pos()).is() to test tag membership
  • Displays biome ID, applicable tags, and ore list with height ranges
  • Hardcoded ore lists by category (COLD_ORES, HOT_ORES, etc.) in OreBiomeFinderItem.java

Adding a New Ore

To add a new ore type (requires MCreator for full integration):

  1. Create the block in MCreator with proper properties (sound type, harvest level, etc.)
  2. Add loot table at src/main/resources/data/custom_ore_gen/loot_table/blocks/{orename}.json (note: loot_table not loot_tables)
  3. Add configured_feature JSON in src/main/resources/data/custom_ore_gen/worldgen/configured_feature/
  4. Add placed_feature JSON in src/main/resources/data/custom_ore_gen/worldgen/placed_feature/
  5. Create biome_modifier JSON in src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/ linking to a biome tag (or create a new tag in tags/worldgen/biome/)
  6. Add BOP entries (optional) to appropriate biome tag JSON files with "required": false wrapper
  7. Update OreBiomeFinderItem.java to add the new ore to the appropriate category list
  8. Add ore type mapping in OreBreakEventHandler.java if you want configurable drops via ConfigurableOreDropsProcedure

User Code Sections

When editing MCreator-generated files, only modify code between:

// Start of user code block [section_name]
// End of user code block [section_name]

For example, in CustomOreGenModItems.java (lines 67-78):

// Start of user code block custom items
public static final Supplier<Item> ORE_BIOME_FINDER = REGISTRY.register("ore_biome_finder", () -> new OreBiomeFinderItem());
// ... armor, paxel registrations
// End of user code block custom items

Important: Custom items like the Ore Biome Finder, Shard Diamond armor, and Paxel are registered in this protected section and will survive MCreator rebuilds.

Event Handlers

The mod uses NeoForge's event system for ore processing:

OreBreakEventHandler

  • Listens to BlockEvent.BreakEvent with @SubscribeEvent
  • Maps custom ore blocks to ore type strings (shard_diamond, concentrated_coal, pure_golden, etc.)
  • Calls ConfigurableOreDropsProcedure.execute() with ore type when player breaks ore with correct tool
  • Supports 10 ore types: shard_diamond, concentrated_coal, pure_golden, impure_iron, concentrated_diamond, lapis, redstone, emerald, copper

EnchantabilityFix

  • Uses ModifyDefaultComponentsEvent to set enchantability values on tools and armor
  • Currently commented out - enchantability not yet applied
  • When active, should set DataComponents.ENCHANTABLE with value 9 (tools) or 14 (armor)

Loot Table Format

NeoForge 1.21 uses loot_table (singular) instead of loot_tables (plural):

  • Location: src/main/resources/data/custom_ore_gen/loot_table/blocks/{orename}.json
  • Includes Silk Touch support via match_tool condition
  • Uses random_sequence for loot table randomization
  • Example structure in deepslatesharddiamondore.json shows Silk Touch → drop block, otherwise drops handled by OreBreakEventHandler

Vanilla Ore Removal

The mod removes vanilla ores via NeoForge biome modifiers (NOT KubeJS anymore):

  • src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/remove_vanilla_ores.json
  • Uses neoforge:remove_features type to remove vanilla ore generation
  • This replaces the old KubeJS automatic script system from Forge 1.20.1

Biomes O' Plenty Integration

The mod includes BOP biome support through biome tag entries. BOP biomes are wrapped with:

{
  "id": "biomesoplenty:biome_name",
  "required": false
}

The "required": false flag ensures the game doesn't crash if BOP isn't installed. When adding new BOP biomes, add them to the appropriate category tag JSON files in tags/worldgen/biome/.

Testing

After making changes:

  1. Run ./gradlew build to verify compilation
  2. Run ./gradlew runClient to test in-game
  3. Check logs in run/logs/ for errors

Enchantment Tags

The mod includes enchantment tags at src/main/resources/data/minecraft/tags/item/enchantable/:

  • armor.json - Marks Shard Diamond armor pieces as enchantable
  • durability.json - Marks tools and armor for durability enchantments
  • mining.json - Marks pickaxes, shovels, and paxel as mining tools
  • weapon.json - Marks axes as weapons

These tags enable proper enchantment behavior for custom items in the enchanting table and anvil.

Important Notes

README Disclaimer

The README.md file contains outdated information referring to Forge 1.20.1. The current codebase uses NeoForge 1.21.1. Always trust gradle.properties and this file for accurate version information.

Recipe Compatibility

The mod includes recipes for:

  • Mekanism: Enriching recipes for concentrated ores and shard diamond
  • Create: Crushing and milling recipes for ore processing
  • Sculk Catalyst: Diamond shard to sculk catalyst conversion

Version Information

  • Minecraft: 1.21.1
  • NeoForge: 21.1.219 (defined in gradle.properties as neo_version)
  • Java: 21 (configured via Java toolchain in build.gradle)
  • Mod Version: 3.0 (defined in gradle.properties as mod_version)

Mod Registration Order

In CustomOreGenMod constructor, registration order is:

  1. CustomOreGenModBlocks.REGISTRY.register(modEventBus) - Blocks must be registered first
  2. CustomOreGenModItems.REGISTRY.register(modEventBus) - Items depend on blocks for BlockItems
  3. CustomOreGenModTabs.REGISTRY.register(modEventBus) - Creative tabs depend on items

Server Work Queue Pattern

The mod includes a server tick work queue (CustomOreGenMod.java:52-69) for deferring execution:

  • queueServerWork(int tick, Runnable action) - Schedule work to run after N server ticks
  • Only executes on server thread (SidedThreadGroups.SERVER)
  • Processed during ServerTickEvent.Post
  • Use this for operations that need to happen after a delay or during gameplay

DeferredRegister Pattern

All registries use NeoForge's DeferredRegister.create(Registries.X, CustomOreGenMod.MODID) pattern. This is the modern NeoForge 1.21 registration method replacing the old Forge registry system.

NeoForge 1.21 Tool Tier Implementation

When creating custom tool items (Tier), you must implement getIncorrectBlocksForDrops():

  • Returns TagKey<Block> or null
  • If null, all blocks can be dropped (current implementation in SharddiamondpickaxeItem.java:38-40)
  • This replaces the old Forge 1.20 getTier() and incorrect blocks logic