# 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 ```bash # 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: ```java // 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**: ```json { "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: ```java // Start of user code block [section_name] // End of user code block [section_name] ``` For example, in `CustomOreGenModItems.java` (lines 67-78): ```java // Start of user code block custom items public static final Supplier 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: ```json { "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` 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