- Delete custom_ore_gen.mcreator (MCreator workspace definition) and the tracked .mcreator/ backup directory; add .mcreator/ to .gitignore - Delete CONFIG_INTEGRATION_GUIDE.md (obsolete MCreator how-to, self-described as historical) - README/CLAUDE/AGENTS: update package path (com.aulyrius.customoregen), drop MCreator workflow instructions, fix stale config/item docs
238 lines
13 KiB
Markdown
238 lines
13 KiB
Markdown
# 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. Originally scaffolded with MCreator, the project is now **fully hand-maintained** - no file is regenerated automatically.
|
|
|
|
**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
|
|
|
|
### Code Ownership
|
|
|
|
The project was originally generated by MCreator but is no longer maintained with it.
|
|
Every file in `src/main/java` is hand-maintained and safe to edit; there is no
|
|
regeneration step and no protected code blocks.
|
|
|
|
### Package Structure
|
|
|
|
```
|
|
com.aulyrius.customoregen/
|
|
├── CustomOreGenMod.java # Main mod class
|
|
├── OresCommand.java # /ores command implementation
|
|
├── OreTypes.java # Block -> ore type mapping (single source of truth)
|
|
├── block/ # Ore block classes (17 blocks)
|
|
├── item/ # Items (Diamond Shard, tools, armor, Paxel, OreBiomeFinder)
|
|
├── config/ # NeoForge configuration system (ModConfigs, ConfigHelper)
|
|
├── event/ # Event handlers (OreBreakEventHandler)
|
|
├── loot/ # CustomOreLootModifier (Global Loot Modifier for drops)
|
|
├── mixin/ # MultiNoiseBiomeSourceMixin (Deep Dark latitude lock)
|
|
├── procedures/ # Game logic (ConfigurableOreDropsProcedure, OreDropMath)
|
|
├── worldgen/ # Latitude zones, density function, placement, biome gating
|
|
└── init/
|
|
├── CustomOreGenModBlocks.java # Block registry (deferred register)
|
|
├── CustomOreGenModItems.java # Item registry
|
|
└── 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/com/aulyrius/customoregen/config/`:
|
|
|
|
- `ModConfigs.java` - NeoForge configuration with nested config classes: `ToolStatsConfig`, `DropsConfig`, `FeatureToggleConfig`, `LatitudeOreConfig`
|
|
- `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**: Wired. Tools read their stats from `TOOL_STATS` config when the config is loaded, with a hardcoded fallback when not yet loaded (e.g. `SharddiamondpickaxeItem.java`: `return ModConfigs.isLoaded() ? ModConfigs.TOOL_STATS.shardDiamondPickaxeDurability.get() : 200;`).
|
|
- **⚠️ Feature Toggles**: Wired (commit `48a0d797`). Toggles in `FeatureToggleConfig` drive ore *generation* via `ConfigGatedFeaturesModifier` + the `config_gated_features` biome modifiers in `data/custom_ore_gen/neoforge/biome_modifier/add_*_ores.json`. A regression test (`ModConfigsTest.testFeatureToggleConfig_declaresAllTogglesReferencedByConfigHelper()`) ensures every toggle string used by `ConfigHelper.isFeatureEnabled()` actually maps to a field on `FeatureToggleConfig`, so a typo can't silently produce a dead toggle. Note: item/block *registration* still always fires (toggling only gates worldgen, not whether the items exist in creative).
|
|
- **⚠️ Ore Generation (gating)**: Feature toggles gate *whether* each ore feature is added (see Feature Toggles above). Vein parameters (size, count, height) are hard-coded in the data-driven worldgen JSONs under `data/custom_ore_gen/worldgen/` (`configured_feature/` + `placed_feature/`), exactly like vanilla; there is no runtime-config-driven ore parameter provider.
|
|
- **Enchantability**: Works natively in 1.21.1 via the enchantable tags (`data/minecraft/tags/item/enchantable/{mining,weapon,armor,durability}.json`, which include all Shard Diamond tools + armor) combined with `Tier.getEnchantmentValue() == 9` on the tool `Tier`s. The dead `EnchantabilityFix.java` class (which referenced the non-existent `DataComponents.ENCHANTABLE` / `net.minecraft.world.item.enchantment.Enchantable` from an earlier 1.20.5-snapshot API) has been removed.
|
|
|
|
### 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**:
|
|
- Both are thin wrappers over `worldgen/OreZoneCatalog.buildZoneReport(x, z)`, which derives
|
|
the zone from the Z coordinate via `LatitudeConfig` (cold/temperate/hot thresholds)
|
|
- Ore lists per zone live in `OreZoneCatalog` (single source of truth)
|
|
|
|
## Adding a New Ore
|
|
|
|
The project is fully hand-maintained (no MCreator). To add a new ore type:
|
|
|
|
1. **Create the block class** in `block/` (copy an existing ore, adjust properties)
|
|
2. **Register block + item** in `init/CustomOreGenModBlocks.java` and `init/CustomOreGenModItems.java`
|
|
3. **Add loot table** at `src/main/resources/data/custom_ore_gen/loot_table/blocks/{orename}.json` (note: `loot_table` not `loot_tables`)
|
|
4. **Add configured_feature** JSON in `src/main/resources/data/custom_ore_gen/worldgen/configured_feature/`
|
|
5. **Add placed_feature** JSON in `src/main/resources/data/custom_ore_gen/worldgen/placed_feature/` (use a `custom_ore_gen:latitude_zone` placement modifier to bind it to a climate zone)
|
|
6. **Create biome_modifier** JSON in `src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/` (use `custom_ore_gen:config_gated_features` to make it config-toggleable)
|
|
7. **Add BOP entries** (optional) to appropriate biome tag JSON files with `"required": false` wrapper
|
|
8. **Update `OreZoneCatalog.java`** to list the new ore in the appropriate zone
|
|
9. **Add the ore type mapping** in `OreTypes.java` + a drop spec in `CustomOreLootModifier` if you want configurable drops
|
|
|
|
## User Code Sections
|
|
|
|
Historical MCreator "user code block" markers were removed - every source file is
|
|
fully editable.
|
|
|
|
## 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
|
|
|
|
### Enchantability
|
|
- Implemented natively via 1.21.1 mechanisms: the Shard Diamond tools + armor are listed in `data/minecraft/tags/item/enchantable/{mining,weapon,armor,durability}.json`, and the tool `Tier`s return `getEnchantmentValue() == 9`.
|
|
- A former `EnchantabilityFix.java` used `ModifyDefaultComponentsEvent` to set a `DataComponents.ENCHANTABLE` component, but that API does not exist in 1.21.1 (only `ENCHANTMENTS`/`ENCHANTMENT_GLINT_OVERRIDE`/`STORED_ENCHANTMENTS` exist on `DataComponents`). The dead class has been deleted.
|
|
|
|
## 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<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
|