From e179baaf252a92516762860483cd693a10d092c0 Mon Sep 17 00:00:00 2001
From: feldenr <135638674+feldenr@users.noreply.github.com>
Date: Mon, 20 Jul 2026 23:11:16 +0200
Subject: [PATCH] feat(worldgen): v4.1 - latitude zones via density function +
Lithosphere
- Replace custom LatitudeBiomeSource/BiomeBand system with
LatitudeSignalDensityFunction + LatitudeZonePlacement (mixin-based)
- Add mandatory Lithosphere (mr_lithosphere) dependency + mixin config
- Override overworld/large_biomes noise_settings for ultra-wide terrain
- Rename remove_vanilla_ores -> z_remove_vanilla_ores (load order)
- Merge cold/hot/tempered biome tags into latitude_*_surface tags
- Rework OresCommand, OreBiomeFinderItem, ModConfigs for new system
- Remove obsolete latitude classes, tests & world preset overrides
- Bump mod_version 3.2 -> 4.1
---
CHANGELOG_4.0.md | 85 +
CHANGELOG_4.1.md | 30 +
CURSEFORGE_DESCRIPTION.md | 176 ++
gradle.properties | 2 +-
.../customoregen/CustomOreGenMod.java | 3 +-
.../mcreator/customoregen/OresCommand.java | 161 +-
.../customoregen/config/ModConfigs.java | 27 +
.../customoregen/item/OreBiomeFinderItem.java | 142 +-
.../mixin/MultiNoiseBiomeSourceMixin.java | 91 +
.../customoregen/worldgen/BiomeBand.java | 130 -
.../worldgen/LatitudeBiomeSource.java | 356 ---
.../customoregen/worldgen/LatitudeConfig.java | 57 +
.../worldgen/LatitudeGameTest.java | 518 ----
.../worldgen/LatitudeMapCommand.java | 219 --
.../customoregen/worldgen/LatitudeMath.java | 133 -
.../LatitudeSignalDensityFunction.java | 62 +
.../worldgen/LatitudeSpawnHandler.java | 118 -
.../worldgen/LatitudeZonePlacement.java | 77 +
.../worldgen/OreAuditHandler.java | 134 -
.../worldgen/WorldGenRegistration.java | 28 +-
.../resources/META-INF/neoforge.mods.toml | 12 +
src/main/resources/custom_ore_gen.mixins.json | 15 +
.../biome_modifier/add_cold_biomes_ores.json | 40 +-
.../biome_modifier/add_hot_biomes_ores.json | 56 +-
.../add_mountain_biomes_ores.json | 24 +-
.../biome_modifier/add_rare_biomes_ores.json | 24 +-
.../add_shard_diamond_ores.json | 30 +-
.../add_tempered_biomes_ores.json | 40 +-
...a_ores.json => z_remove_vanilla_ores.json} | 19 +-
.../tags/worldgen/biome/cold_biomes.json | 68 -
.../tags/worldgen/biome/hot_biomes.json | 106 -
.../worldgen/biome/latitude_cold_surface.json | 18 +-
.../worldgen/biome/latitude_hot_surface.json | 34 +-
.../biome/latitude_temperate_surface.json | 60 +-
.../tags/worldgen/biome/mountain_biomes.json | 3 -
.../tags/worldgen/biome/rare_biomes.json | 1 -
.../tags/worldgen/biome/tempered_biomes.json | 109 -
.../concentratedcoalore.json | 2 +-
.../configured_feature/copperhighore.json | 15 +-
.../configured_feature/copperlowerore.json | 15 +-
.../deepslatediamondore.json | 2 +-
.../configured_feature/deepslateironore.json | 2 +-
.../configured_feature/deepslatelapisore.json | 2 +-
.../deepslatepuregoldenore.json | 2 +-
.../deepslateredstoneore.json | 2 +-
.../configured_feature/highemeraldore.json | 2 +-
.../worldgen/configured_feature/ironore.json | 2 +-
.../worldgen/configured_feature/lapisore.json | 2 +-
.../configured_feature/loweremeraldore.json | 2 +-
.../configured_feature/puregoldenore.json | 2 +-
.../configured_feature/redstoneore.json | 2 +-
.../density_function/latitude_signal.json | 3 +
.../latitude_temperature.json | 22 +
.../placed_feature/concentratedcoalore.json | 5 +-
.../placed_feature/copperhighore.json | 3 +-
.../placed_feature/copperlowerore.json | 3 +-
.../placed_feature/deepslatediamondore.json | 5 +-
.../placed_feature/deepslateironore.json | 3 +-
.../placed_feature/deepslatelapisore.json | 3 +-
.../deepslatepuregoldenore.json | 3 +-
.../placed_feature/deepslateredstoneore.json | 3 +-
.../worldgen/placed_feature/ironore.json | 3 +-
.../worldgen/placed_feature/lapisore.json | 3 +-
.../placed_feature/puregoldenore.json | 3 +-
.../worldgen/placed_feature/redstoneore.json | 3 +-
.../world_preset/ultra_wide_biome.json | 36 -
.../tags/worldgen/world_preset/normal.json | 11 -
.../worldgen/noise_settings/large_biomes.json | 2473 ++++++++++++++++
.../worldgen/noise_settings/overworld.json | 2535 +++++++++++++++++
.../customoregen/worldgen/BiomeBandTest.java | 196 --
.../worldgen/LatitudeMathTest.java | 315 --
71 files changed, 6061 insertions(+), 2832 deletions(-)
create mode 100644 CHANGELOG_4.0.md
create mode 100644 CHANGELOG_4.1.md
create mode 100644 CURSEFORGE_DESCRIPTION.md
create mode 100644 src/main/java/net/mcreator/customoregen/mixin/MultiNoiseBiomeSourceMixin.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/BiomeBand.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeBiomeSource.java
create mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeConfig.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeGameTest.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeMapCommand.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeMath.java
create mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeSignalDensityFunction.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeSpawnHandler.java
create mode 100644 src/main/java/net/mcreator/customoregen/worldgen/LatitudeZonePlacement.java
delete mode 100644 src/main/java/net/mcreator/customoregen/worldgen/OreAuditHandler.java
create mode 100644 src/main/resources/custom_ore_gen.mixins.json
rename src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/{remove_vanilla_ores.json => z_remove_vanilla_ores.json} (85%)
delete mode 100644 src/main/resources/data/custom_ore_gen/tags/worldgen/biome/cold_biomes.json
delete mode 100644 src/main/resources/data/custom_ore_gen/tags/worldgen/biome/hot_biomes.json
delete mode 100644 src/main/resources/data/custom_ore_gen/tags/worldgen/biome/tempered_biomes.json
create mode 100644 src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_signal.json
create mode 100644 src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_temperature.json
delete mode 100644 src/main/resources/data/custom_ore_gen/worldgen/world_preset/ultra_wide_biome.json
delete mode 100644 src/main/resources/data/minecraft/tags/worldgen/world_preset/normal.json
create mode 100644 src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json
create mode 100644 src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json
delete mode 100644 src/test/java/net/mcreator/customoregen/worldgen/BiomeBandTest.java
delete mode 100644 src/test/java/net/mcreator/customoregen/worldgen/LatitudeMathTest.java
diff --git a/CHANGELOG_4.0.md b/CHANGELOG_4.0.md
new file mode 100644
index 00000000..382e6da9
--- /dev/null
+++ b/CHANGELOG_4.0.md
@@ -0,0 +1,85 @@
+# Custom Ore Gen — 4.0 Changelog
+
+**Custom Ore Gen 4.0** is a full rewrite, rebuilt from the ground up for **NeoForge 1.21.1**. It drops KubeJS entirely, introduces a brand-new **latitude-based ore system**, ships custom **ultra-wide terrain** via the Lithosphere companion, and turns the **Deep Dark into a legendary northern feature**.
+
+This is the biggest update in the mod's history. Existing worlds from 2.x are **not** compatible — create a new world.
+
+---
+
+## 🆕 New Features
+
+* **Latitude-based ore generation** — Ores are now distributed by your **Z coordinate** instead of biome categories. The world is split into three bands:
+ * ❄️ **Cold** (Z < −8000, north): Lapis, Deepslate Diamond
+ * 🔥 **Hot** (Z > 8000, south): Pure Gold, Redstone, Copper
+ * 🌳 **Temperate** (middle): Iron, Concentrated Coal
+ * Works with **any biome mod** out of the box — no per-biome classification needed.
+* **Legendary Deep Dark** — The Deep Dark now only generates in cold northern latitudes, making it a true endgame destination rather than a random underground encounter. (Implemented via a safe, targeted mixin.)
+* **Custom ultra-wide terrain** — Ships a handcrafted world generation through the new **Lithosphere** companion mod (now a required dependency).
+* **Config-gated feature toggles** — A custom `ConfigGatedFeaturesModifier` makes the config feature toggles (`concentratedOres`, `impureOres`, `vanillaOreVariants`, etc.) actually gate world generation at runtime.
+* **Global Loot Modifier for drops** — Replaced fragile event-based drops with a proper data-driven loot modifier (also fixed a crash with the Create drill).
+* **Color-coded `/ores` command & Ore Biome Finder** — Output is now color-coded per zone (cold = aqua, hot = gold, temperate = green, shard ores = light purple) and clearly explains that the **Z coordinate** determines your zone.
+* **Configurable zone thresholds** — The cold/hot thresholds (default Z = ±8000) are now adjustable in `custom-ore-gen-common.toml`.
+* **Create & Mekanism compat** — Standalone-safe recipes for crushing, milling, mixing and enriching shard diamonds.
+
+---
+
+## ⚙️ Changes
+
+* **Migrated from Forge 1.20.1 → NeoForge 1.21.1.**
+* **Removed KubeJS dependency entirely.** Vanilla ores are now removed via NeoForge **biome modifiers** (`z_remove_vanilla_ores.json`) — no startup scripts, nothing to run.
+* **New required dependency: Lithosphere 1.7+** — provides the custom terrain the mod is balanced for.
+* Tool & armor stats are now **linked to config** — durability, speed, damage and armor values can all be tuned.
+* Emeralds remain **biome-based** (mountain and rare-biome tags), since they're tied to terrain, not latitude.
+* Rebalanced ore drop counts and XP to align with vanilla 1.21.
+* Iron and Gold ores now **ignore Fortune** like vanilla.
+* Paxel now affects every block mineable by pickaxe/shovel/axe tags.
+* Rebalanced Diamond Shard tier as a clear bridge between iron and diamond.
+
+---
+
+## 🐛 Bug Fixes
+
+* **Vanilla diamond leaked everywhere** — All **4** vanilla diamond placed features are now removed (`ore_diamond`, `ore_diamond_buried`, `ore_diamond_large`, `ore_diamond_medium`). Previously only 2 were removed, so buried/medium diamonds spawned in every biome.
+* **Copper showed the wrong texture in deepslate** — Custom copper now uses the vanilla two-target approach (stone → `copper_ore`, deepslate → `deepslate_copper_ore`) instead of forcing `copper_ore` everywhere.
+* **`/ores` always reported temperate** — `zoneName()` was reading static fields instead of the config getters; it now reads the live thresholds.
+* **Garbage `6a9` prefix in ore listings** — Removed a broken color-code remnant that appeared in front of every ore name.
+* **Diamond rate was way too high in cold zones** — Reduced the custom Deepslate Diamond `count` from 6 → 3 (combined with the vanilla leak fix, diamonds are now properly rare).
+* **Server hung on startup** — Removed the `SpawnRelocator` and `OreAuditHandler` entirely. They forced synchronous chunk generation on the main server thread (a known cause of deadlocks and world corruption) and the audit handler shipped a `System.exit(0)` hard-kill. Both were dev-only diagnostics that never belonged in a release.
+* **Badlands gold leaked into non-hot zones** — Added `ore_gold_extra` to the vanilla removal list.
+* **Cross-climate tag leaks** — Removed copper/gold appearing in temperate spawns due to overlapping surface tags.
+* **Caves piercing the surface** — Reverted the stretched terrain that caused cave openings to break the surface.
+* **Create processing recipes** — Repaired and made them standalone-safe (no leftover references to removed ores).
+* Various startup crashes, build errors and config-load race conditions resolved.
+
+---
+
+## 🗑️ Removals
+
+* **KubeJS** — no longer used or required.
+* Auto-generated `kubejs/startup_scripts/custom_ore_gen_remove_vanilla_ores.js` — replaced by biome modifiers.
+* Dead config categories, unused `EnchantabilityFix` class, and redundant `tectonic`/custom noise settings.
+* Legacy biome-tag surface files (`latitude_cold_surface`, `latitude_hot_surface`, `latitude_temperate_surface`, `cold_biomes`, `hot_biomes`, `tempered_biomes`, etc.) — superseded by the Z-based system.
+
+---
+
+## 🧪 Technical / Internal
+
+* Mixed-in `MultiNoiseBiomeSource` to intercept Deep Dark biome resolution safely (Mojmap, no refmap needed on production).
+* Custom `LatitudeZonePlacement` placement modifier filters ore placement by Z at the placed-feature level.
+* Comprehensive test suite added: `OresCommandTest`, `ModConfigsTest`, `ConfigurableOreDropsProcedureTest`, `OreDropMathTest`, plus an automated GameTest server for latitude validation.
+* Cleaned up block/item classes and migrated the entire test suite to NeoForge.
+
+---
+
+## 📦 Requirements
+
+* Minecraft 1.21.1
+* NeoForge 21.1.x
+* **Lithosphere 1.7+** (required)
+* Biomes O' Plenty, Create, Mekanism (optional, recommended)
+
+---
+
+> ⚠️ **Create a NEW world after updating.** Chunks generated before 4.0 keep their old ore distribution.
+
+**Happy mining!** 🌍⛏️✨
diff --git a/CHANGELOG_4.1.md b/CHANGELOG_4.1.md
new file mode 100644
index 00000000..daf5cbbc
--- /dev/null
+++ b/CHANGELOG_4.1.md
@@ -0,0 +1,30 @@
+# Custom Ore Gen — 4.1
+
+A hotfix release that removes developer-only diagnostics that could destabilise dedicated servers. **No gameplay changes** — all ore generation, the Diamond Shard tier, the Deep Dark lock and mod compatibility are identical to 4.0.
+
+---
+
+## 🐛 Bug Fixes
+
+* **Removed world/server-corrupting code** — Three developer-only diagnostic classes were accidentally shipped in 4.0. They have been removed entirely:
+ * `OreAuditHandler` — contained a `System.exit(0)` hard-kill that would terminate the server process, and forced chunk generation from a separate thread (a classic cause of chunk corruption).
+ * `SpawnRelocator` — forced synchronous chunk generation on the main server thread during startup, causing deadlocks and hang.
+ * `GenerationStabilityTest` — a GameTest utility that had no place in a release build.
+* None of these classes were referenced by any gameplay code; removing them has **zero impact** on how the mod plays.
+
+---
+
+## 🔄 Changes
+
+* Spawn-point behaviour reverts to vanilla (the removed `SpawnRelocator` no longer moves the spawn). Since the temperate band is 16,000 blocks wide, the vast majority of spawns still land in a balanced ore zone.
+
+---
+
+## ✅ Verification
+
+* No `System.exit`, `Runtime.halt`, forced chunk loading (`getChunkAt`/`getChunk`), manual threads or `setBlock` calls remain anywhere in the codebase.
+* Build and unit tests pass.
+
+---
+
+**Full build:** Minecraft 1.21.1 · NeoForge 21.1.x · Lithosphere 1.7+ (required)
diff --git a/CURSEFORGE_DESCRIPTION.md b/CURSEFORGE_DESCRIPTION.md
new file mode 100644
index 00000000..6a605a00
--- /dev/null
+++ b/CURSEFORGE_DESCRIPTION.md
@@ -0,0 +1,176 @@
+# 🔧 Custom Ore Gen
+
+**Custom Ore Gen** completely overhauls Minecraft's ore generation by replacing vanilla distribution with a **latitude-based system** driven by the world's Z coordinate, and adds a complete intermediate equipment tier between iron and diamond: **Diamond Shards**.
+
+After months of reworking, **version 4.0** is a full rewrite — rebuilt from the ground up for **NeoForge 1.21.1**, dropping KubeJS entirely in favor of fully data-driven biome modifiers, and introducing a brand-new world of latitude exploration.
+
+***
+
+## 🎯 Overview
+
+A mod that:
+
+* Replaces **all** vanilla overworld ore generation with a **latitude system** (north = cold, south = hot, middle = temperate)
+* Adds a new intermediate equipment tier: **Diamond Shards**
+* Encourages **north/south exploration** to gather specific resources
+* Locks the **Deep Dark** to cold northern latitudes as a legendary feature
+* The temperate band is **16,000 blocks wide** (Z = −8000 to +8000), so most spawns already land in a balanced area
+* Ships custom **ultra-wide terrain** through its **Lithosphere** companion mod
+* Automatically integrates with **Biomes O' Plenty**, **Create** and **Mekanism**
+
+***
+
+## 🌍 Latitude-Based Ore Generation
+
+The world is split into three latitude bands running along the **Z axis**. Travel north or south to change which ores you can find — *your Z coordinate, not your biome, decides the ores* (Emeralds being the biome-tagged exception).
+
+| Zone | Direction | Ores |
+| --- | --- | --- |
+| ❄️ **Cold** | North (Z < -8000) | Lapis, Deepslate Diamond |
+| 🔥 **Hot** | South (Z > 8000) | Pure Gold, Redstone, Copper |
+| 🌳 **Temperate** | Middle (-8000 → 8000) | Iron, Concentrated Coal |
+| ⛰️ **Mountain biomes** | Anywhere (by biome tag) | High Emerald |
+| ✨ **Rare biomes** | Anywhere (by biome tag) | Lower Emerald |
+| 🔷 **All zones** | Everywhere | Deepslate Shard Diamond, Shard Diamond Block |
+
+> ⚠️ **Note**: _Deepslate Shard Diamond Ore_ is the **only progression ore that spawns in ALL zones**, ensuring accessible early-game progression wherever you start. The temperate band is huge (16,000 blocks), so you almost always start in a balanced ore zone.
+
+🧭 Use the **Ore Biome Finder** item or the **`/ores`** command to see exactly which ores are available at your current Z coordinate — the output is **color-coded per zone** (cold = aqua, hot = gold, temperate = green, shard ores = light purple).
+
+***
+
+## 💎 Diamond Shard Tier — New Progression
+
+A complete set of tools and armor that bridges the gap between iron and diamond.
+
+### ⚙️ **Available Equipment**
+
+| Type | Components | Durability |
+| --- | --- | --- |
+| **Tools** (Pickaxe, Axe, Shovel) | Diamond Shards | 450 |
+| **Paxel** (3-in-1 tool) | Diamond Shards | 800 |
+| **Full Armor Set** | Diamond Shards + 2 Diamonds | 17 protection, Toughness 1.0 |
+
+> ✅ **The Paxel** combines the functions of **pickaxe, axe, and shovel** into a single tool — affecting every block mineable by those tags.
+
+> 🛠️ All stats above are the **defaults** — every durability, speed and damage value, plus the cold/hot zone thresholds and ore drops, is configurable in `custom-ore-gen-common.toml`.
+
+### 🧪 **Shard → Diamond Conversion**
+
+9 Diamond Shards → 1 Diamond (3×3 crafting grid).
+
+### 🛡️ **Armor Recipes**
+
+* **Helmet**: 5 Diamond Shards
+* **Chestplate**: 8 Diamond Shards + 1 Diamond
+* **Leggings**: 7 Diamond Shards + 1 Diamond
+* **Boots**: 4 Diamond Shards
+
+> ⚙️ **Repair** any Diamond Shard equipment with Diamond Shards on an anvil.
+
+***
+
+## 🔍 Ore Biome Finder
+
+A handy tool to instantly know which ores are available at your current latitude.
+
+🎮 **Alternatives**:
+
+* Craft the **Ore Biome Finder** item (check JEI for the recipe).
+* Use the **`/ores`** (or `/ore`) command — it shows your X/Z position, the zone determined by Z, the cold/hot thresholds, and a **color-coded** list of findable ores.
+
+***
+
+## 📦 Installation & Dependencies
+
+### ⚠️ **Mandatory Requirements**
+
+* **Minecraft**: 1.21.1
+* **NeoForge**: 21.1.x
+* **Lithosphere**: 1.7+ _(required — provides the custom ultra-wide terrain the mod is balanced for)_
+
+### 🌐 **Optional but Recommended**
+
+* **Biomes O' Plenty** — ore generation automatically extends to all its biomes.
+* **Create** — ore-processing compat (crushing/milling shard diamond ore, mixing shards → diamond).
+* **Mekanism** — enriching compat for shard diamonds.
+
+> 🚫 The mod does **not** use KubeJS anymore. Vanilla ores are fully removed via NeoForge **biome modifiers** — no scripts, nothing to run.
+
+***
+
+## 🎮 Gameplay & Progression
+
+1. **Initial Stage**
+ Start in the temperate band and mine **Deepslate Shard Diamond Ore** (available everywhere) to obtain **Diamond Shards**.
+
+2. **First Equipment**
+ Craft Diamond Shard tools (or the versatile Paxel) for better efficiency than iron.
+
+3. **Targeted Exploration**
+ Travel north or south along the Z axis to reach different ore zones:
+ * **North (Cold)**: Lapis and Deepslate Diamonds
+ * **South (Hot)**: Pure Gold, Redstone, Copper
+ * **Mountain biomes**: High Emeralds
+ * **Rare biomes**: Lower Emeralds
+
+4. **Final Progression**
+ Combine 9 Diamond Shards to create a regular Diamond and access vanilla diamond equipment.
+
+***
+
+## 📊 Equipment Statistics Comparison
+
+| Material | Protection | Chestplate Durability |
+| --- | --- | --- |
+| Iron | 15 | 240 |
+| **Diamond Shard** | **17** | **300** |
+| Diamond | 20 | 528 |
+
+***
+
+## 🌟 Key Features
+
+* 🗺️ **Latitude Exploration**: the Z coordinate — not the biome — decides your ores
+* 🌌 **Legendary Deep Dark**: locked to cold northern latitudes only (via a safe mixin)
+* 🚀 **Custom Ultra-Wide Terrain**: ships with Lithosphere for a fresher, wider world
+* ⚔️ **Balanced Progression**: Diamond Shard tier bridges the iron–diamond gap
+* 🚫 **No Vanilla Ores**: fully removed via data-driven biome modifiers (no scripts)
+* 🌍 **Modpack Friendly**: automatic integration with any biome mod through the Z system
+* 🎨 **Dedicated Creative Tab**: all mod items in the "Custom Ore Gen" tab
+* 🛠️ **Versatile Tools**: the Paxel saves inventory space
+* 📊 **In-game Info**: Finder item + `/ores` command with color-coded zones
+* ⚙️ **Fully Configurable**: zone thresholds, tool stats, armor values and ore drops
+
+***
+
+## 🆕 What's New in 4.0
+
+Version 4.0 is a ground-up rebuild. Highlights:
+
+* **Full NeoForge 1.21.1 port** — left Forge 1.20.1 and KubeJS behind; everything is now data-driven biome modifiers.
+* **Latitude ore system** — ores are now distributed by **Z coordinate** instead of biome categories, so it works with *any* biome mod out of the box.
+* **Ultra-wide custom terrain** — bundled through the **Lithosphere** companion mod.
+* **Legendary Deep Dark** — the Deep Dark now only generates in cold northern latitudes, making it a true endgame destination.
+* **Create & Mekanism compat** — recipes for crushing, milling, mixing and enriching shard diamonds.
+* **Color-coded `/ores` & Ore Finder** — clear, readable output that explains the Z mechanic.
+* **Polished ore behaviour** — all 4 vanilla diamond features are properly removed, and copper now uses the correct deepslate texture underground.
+
+> 💡 Existing worlds from older versions are **not** compatible — create a **new world** after installing 4.0.
+
+***
+
+## 📝 Important Notes
+
+* ⚠️ **Create a NEW world** after installing. Chunks generated before installation keep their old ore distribution.
+* The cold/hot zone thresholds default to **Z = ±8000** but are fully adjustable in the config.
+* Emeralds remain **biome-based** (mountain and rare-biome tags), not latitude-based.
+* All Diamond Shard equipment can be repaired with Diamond Shards.
+
+***
+
+### 🎯 **Why Choose Custom Ore Gen?**
+
+Because it brings **logic to exploration** (travel the world to find specific ores), **smoother progression** (a real iron-to-diamond bridge), and **seamless integration** with many modded biomes — all without tedious configuration.
+
+> **Happy mining!** 🌍⛏️✨
diff --git a/gradle.properties b/gradle.properties
index f4746506..5909746b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx4G
org.gradle.daemon=true
# Mod Properties
-mod_version=3.2
+mod_version=4.1
mod_id=custom_ore_gen
mod_name=Custom Ore Gen
mod_group_id=com.aulyrius.custom_ore_gen
diff --git a/src/main/java/net/mcreator/customoregen/CustomOreGenMod.java b/src/main/java/net/mcreator/customoregen/CustomOreGenMod.java
index cbd075f0..28ad76ad 100644
--- a/src/main/java/net/mcreator/customoregen/CustomOreGenMod.java
+++ b/src/main/java/net/mcreator/customoregen/CustomOreGenMod.java
@@ -59,8 +59,9 @@ public class CustomOreGenMod {
LOOT_MODIFIERS.register(modEventBus);
// Start of user code block mod init
- WorldGenRegistration.BIOME_SOURCES.register(modEventBus);
WorldGenRegistration.BIOME_MODIFIER_SERIALIZERS.register(modEventBus);
+ WorldGenRegistration.DENSITY_FUNCTION_TYPES.register(modEventBus);
+ WorldGenRegistration.PLACEMENT_MODIFIERS.register(modEventBus);
// End of user code block mod init
}
diff --git a/src/main/java/net/mcreator/customoregen/OresCommand.java b/src/main/java/net/mcreator/customoregen/OresCommand.java
index 88d96d6c..8ff2ccc8 100644
--- a/src/main/java/net/mcreator/customoregen/OresCommand.java
+++ b/src/main/java/net/mcreator/customoregen/OresCommand.java
@@ -2,153 +2,104 @@ package net.mcreator.customoregen;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
+import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
-import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.tags.TagKey;
-import net.minecraft.world.level.biome.Biome;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.common.Mod;
import net.neoforged.fml.common.EventBusSubscriber;
import java.util.*;
+import net.mcreator.customoregen.worldgen.LatitudeConfig;
+
@EventBusSubscriber(modid = CustomOreGenMod.MODID, bus = EventBusSubscriber.Bus.GAME)
public class OresCommand {
- // Tags personnalisés du mod
- private static final TagKey COLD_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "cold_biomes"));
- private static final TagKey HOT_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "hot_biomes"));
- private static final TagKey MOUNTAIN_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "mountain_biomes"));
- private static final TagKey TEMPERED_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "tempered_biomes"));
- private static final TagKey RARE_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "rare_biomes"));
-
- // Minerais par catégorie (mappé avec les biome modifiers)
private static final List COLD_ORES = Arrays.asList(
- "Lapis (stone) [Y: 0 à 32]",
- "Lapis (deepslate) [Y: -64 à 0]",
- "Diamant (deepslate) [Y: -64 à 0]");
+ "Lapis (stone) [Y: 0 a 32]",
+ "Lapis (deepslate) [Y: -64 a 0]",
+ "Diamant (deepslate) [Y: -64 a 0]");
private static final List HOT_ORES = Arrays.asList(
- "Or Pur (stone) [Y: 0 à 256]",
- "Or Pur (deepslate) [Y: -64 à 0]",
- "Redstone (stone) [Y: -10 à 20]",
- "Redstone (deepslate) [Y: -80 à -30]",
- "Cuivre (haut) [Y: 15 à 256]",
- "Cuivre (bas) [Y: -64 à 0]");
+ "Or (stone) [Y: 0 a 320]",
+ "Or (deepslate) [Y: -64 a 0]",
+ "Cuivre (haut) [Y: 15 a 320]",
+ "Cuivre (bas) [Y: -64 a 0]",
+ "Redstone (stone) [Y: -10 a 20]",
+ "Redstone (deepslate) [Y: -80 a -30]");
- private static final List MOUNTAIN_ORES = Arrays.asList(
- "Emeraude (haute altitude) [Y: 0 à 64]");
-
- private static final List TEMPERED_ORES = Arrays.asList(
- "Charbon Concentre [Y: 0 à 70]",
- "Fer (stone) [Y: 0 à 100]",
- "Fer (deepslate) [Y: -64 à 0]");
-
- private static final List RARE_ORES = Arrays.asList(
- "Emeraude (basse altitude) [Y: -64 à 0]");
+ private static final List TEMPERATE_ORES = Arrays.asList(
+ "Fer (stone) [Y: 0 a 100]",
+ "Fer (deepslate) [Y: -64 a 0]",
+ "Charbon concentre [Y: 0 a 70]");
private static final List EVERYWHERE_ORES = Arrays.asList(
- "Diamant Shard (deepslate) [Y: -64 à -40]",
- "Bloc Diamant Shard [Y: 0 à 15]");
+ "Diamant Shard (deepslate) [Y: -64 a -40]",
+ "Bloc Diamant Shard [Y: 0 a 15]");
@SubscribeEvent
public static void onRegisterCommands(RegisterCommandsEvent event) {
- CommandDispatcher dispatcher = event.getDispatcher();
-
- // Niveau de permission 2 = OP (Admin level)
- dispatcher.register(Commands.literal("ores")
+ event.getDispatcher().register(Commands.literal("ores")
.requires(source -> source.hasPermission(2))
.executes(OresCommand::executeOres));
-
- dispatcher.register(Commands.literal("ore")
+ event.getDispatcher().register(Commands.literal("ore")
.requires(source -> source.hasPermission(2))
.executes(OresCommand::executeOres));
}
private static int executeOres(CommandContext context) {
- if (!(context.getSource().getEntity() instanceof net.minecraft.world.entity.player.Player)) {
- context.getSource()
- .sendFailure(Component.literal("Cette commande ne peut etre utilisee que par un joueur"));
+ if (!(context.getSource().getEntity() instanceof net.minecraft.world.entity.player.Player player)) {
+ context.getSource().sendFailure(Component.literal("Cette commande ne peut etre utilisee que par un joueur"));
return 0;
}
- net.minecraft.world.entity.player.Player player = (net.minecraft.world.entity.player.Player) context.getSource()
- .getEntity();
- net.minecraft.world.level.Level level = player.level();
- net.minecraft.core.BlockPos pos = player.blockPosition();
+ int x = player.blockPosition().getX();
+ int z = player.blockPosition().getZ();
- var biomeHolder = level.getBiome(pos);
- ResourceKey biomeKey = biomeHolder.unwrapKey()
- .orElse(ResourceKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("minecraft", "plains")));
- ResourceLocation biomeId = biomeKey.location();
- String biomeName = biomeId.getPath();
+ String zone = LatitudeConfig.zoneName(z);
+ int coldZ = LatitudeConfig.getColdZoneZ();
+ int hotZ = LatitudeConfig.getHotZoneZ();
+ ChatFormatting zoneColor = zoneColor(zone);
- context.getSource().sendSuccess(() -> Component.literal("=== Minerais dans: " + biomeName + " ==="), true);
- context.getSource().sendSuccess(() -> Component.literal("Biome ID: " + biomeId), true);
+ context.getSource().sendSuccess(() -> Component.literal(
+ "=== Position: X=" + x + " Z=" + z + " ===").withStyle(ChatFormatting.GRAY), true);
+ context.getSource().sendSuccess(() -> Component.literal(
+ "Zone determinee par la coordonnee Z : " + zone).withStyle(zoneColor), true);
+ context.getSource().sendSuccess(() -> Component.literal(
+ "Z < " + coldZ + " = froid | " + coldZ + " a " + hotZ + " = tempere | Z > " + hotZ + " = chaud")
+ .withStyle(ChatFormatting.GRAY), true);
- // Vérifier les tags personnalisés du mod
- Set foundTags = new HashSet<>();
- List foundOres = new ArrayList<>();
-
- // Vérifier chaque tag de biome et ajouter les minerais correspondants
- if (isBiomeInTag(level, pos, COLD_BIOMES_TAG)) {
- foundTags.add("cold_biomes");
- foundOres.addAll(COLD_ORES);
- }
- if (isBiomeInTag(level, pos, HOT_BIOMES_TAG)) {
- foundTags.add("hot_biomes");
- foundOres.addAll(HOT_ORES);
- }
- if (isBiomeInTag(level, pos, MOUNTAIN_BIOMES_TAG)) {
- foundTags.add("mountain_biomes");
- foundOres.addAll(MOUNTAIN_ORES);
- }
- if (isBiomeInTag(level, pos, TEMPERED_BIOMES_TAG)) {
- foundTags.add("tempered_biomes");
- foundOres.addAll(TEMPERED_ORES);
- }
- if (isBiomeInTag(level, pos, RARE_BIOMES_TAG)) {
- foundTags.add("rare_biomes");
- foundOres.addAll(RARE_ORES);
+ List zoneOres = new ArrayList<>();
+ switch (zone) {
+ case "COLD" -> zoneOres.addAll(COLD_ORES);
+ case "HOT" -> zoneOres.addAll(HOT_ORES);
+ case "TEMPERATE" -> zoneOres.addAll(TEMPERATE_ORES);
}
- // Ajouter les minerais présents partout
- foundOres.addAll(EVERYWHERE_ORES);
+ Set allOres = new LinkedHashSet<>(zoneOres);
+ allOres.addAll(EVERYWHERE_ORES);
- // Afficher les tags trouvés
- if (!foundTags.isEmpty()) {
- context.getSource().sendSuccess(() -> Component.literal("Tags du mod: " + String.join(", ", foundTags)),
- true);
- } else {
- context.getSource().sendSuccess(() -> Component.literal("Tags du mod: aucun"), true);
+ context.getSource().sendSuccess(() -> Component.literal(
+ "Minerais trouvables (" + allOres.size() + ") :").withStyle(ChatFormatting.WHITE), true);
+ for (String ore : zoneOres) {
+ context.getSource().sendSuccess(() -> Component.literal(" * " + ore).withStyle(zoneColor), true);
}
-
- // Afficher les minerais (sans doublons)
- if (!foundOres.isEmpty()) {
- Set uniqueOres = new LinkedHashSet<>(foundOres);
- context.getSource().sendSuccess(() -> Component.literal("Minerais trouvables:"), true);
- for (String ore : uniqueOres) {
- context.getSource().sendSuccess(() -> Component.literal(" * " + ore), true);
- }
- } else {
- context.getSource().sendSuccess(() -> Component.literal("Aucun minerai specifique"), true);
+ for (String ore : EVERYWHERE_ORES) {
+ context.getSource().sendSuccess(() -> Component.literal(" * " + ore)
+ .withStyle(ChatFormatting.LIGHT_PURPLE), true);
}
return 1;
}
- private static boolean isBiomeInTag(net.minecraft.world.level.Level level, net.minecraft.core.BlockPos pos,
- TagKey tag) {
- return level.getBiome(pos).is(tag);
+ private static ChatFormatting zoneColor(String zone) {
+ return switch (zone) {
+ case "COLD" -> ChatFormatting.AQUA;
+ case "HOT" -> ChatFormatting.GOLD;
+ case "TEMPERATE" -> ChatFormatting.GREEN;
+ default -> ChatFormatting.WHITE;
+ };
}
}
diff --git a/src/main/java/net/mcreator/customoregen/config/ModConfigs.java b/src/main/java/net/mcreator/customoregen/config/ModConfigs.java
index 60417ec3..78efda5d 100644
--- a/src/main/java/net/mcreator/customoregen/config/ModConfigs.java
+++ b/src/main/java/net/mcreator/customoregen/config/ModConfigs.java
@@ -16,6 +16,7 @@ public class ModConfigs {
TOOL_STATS = new ToolStatsConfig(BUILDER);
DROPS = new DropsConfig(BUILDER);
FEATURES = new FeatureToggleConfig(BUILDER);
+ LATITUDE_ORE = new LatitudeOreConfig(BUILDER);
BUILDER.pop();
SPEC = BUILDER.build();
@@ -318,4 +319,30 @@ public class ModConfigs {
builder.pop();
}
}
+
+ // Configuration for the latitude ore distribution system
+ public static class LatitudeOreConfig {
+ public final ModConfigSpec.ConfigValue coldZoneZ;
+ public final ModConfigSpec.ConfigValue hotZoneZ;
+
+ public LatitudeOreConfig(ModConfigSpec.Builder builder) {
+ builder.push("latitude_ore_zones");
+
+ coldZoneZ = builder
+ .comment("Z coordinate below which is the COLD ore zone (north). Default: -8000",
+ "Example: -8000 means Z < -8000 gets cold ores (lapis, diamond)",
+ "Changing this also shifts the temperature latitude scale.")
+ .defineInRange("coldZoneZ", -8000, -32000, 0);
+
+ hotZoneZ = builder
+ .comment("Z coordinate above which is the HOT ore zone (south). Default: 8000",
+ "Example: 8000 means Z > 8000 gets hot ores (copper, redstone, gold)",
+ "Changing this also shifts the temperature latitude scale.")
+ .defineInRange("hotZoneZ", 8000, 0, 32000);
+
+ builder.pop();
+ }
+ }
+
+ public static final LatitudeOreConfig LATITUDE_ORE;
}
diff --git a/src/main/java/net/mcreator/customoregen/item/OreBiomeFinderItem.java b/src/main/java/net/mcreator/customoregen/item/OreBiomeFinderItem.java
index 4d670beb..59f0caa7 100644
--- a/src/main/java/net/mcreator/customoregen/item/OreBiomeFinderItem.java
+++ b/src/main/java/net/mcreator/customoregen/item/OreBiomeFinderItem.java
@@ -1,63 +1,41 @@
package net.mcreator.customoregen.item;
-import net.minecraft.core.registries.Registries;
+import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
-import net.minecraft.core.BlockPos;
-import net.minecraft.world.level.biome.Biome;
import java.util.*;
+import net.mcreator.customoregen.worldgen.LatitudeConfig;
+
public class OreBiomeFinderItem extends Item {
- // Tags personnalisés du mod
- private static final TagKey COLD_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "cold_biomes"));
- private static final TagKey HOT_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "hot_biomes"));
- private static final TagKey MOUNTAIN_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "mountain_biomes"));
- private static final TagKey TEMPERED_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "tempered_biomes"));
- private static final TagKey RARE_BIOMES_TAG = TagKey.create(Registries.BIOME,
- ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "rare_biomes"));
-
- // Minerais par catégorie
private static final List COLD_ORES = Arrays.asList(
- "Lapis (stone) [Y: 0 à 32]",
- "Lapis (deepslate) [Y: -64 à 0]",
- "Diamant (deepslate) [Y: -64 à 0]");
+ "Lapis (stone) [Y: 0 a 32]",
+ "Lapis (deepslate) [Y: -64 a 0]",
+ "Diamant (deepslate) [Y: -64 a 0]");
private static final List HOT_ORES = Arrays.asList(
- "Or Pur (stone) [Y: 0 à 256]",
- "Or Pur (deepslate) [Y: -64 à 0]",
- "Redstone (stone) [Y: -10 à 20]",
- "Redstone (deepslate) [Y: -80 à -30]",
- "Cuivre (haut) [Y: 15 à 256]",
- "Cuivre (bas) [Y: -64 à 0]");
+ "Or (stone) [Y: 0 a 320]",
+ "Or (deepslate) [Y: -64 a 0]",
+ "Cuivre (haut) [Y: 15 a 320]",
+ "Cuivre (bas) [Y: -64 a 0]",
+ "Redstone (stone) [Y: -10 a 20]",
+ "Redstone (deepslate) [Y: -80 a -30]");
- private static final List MOUNTAIN_ORES = Arrays.asList(
- "Emeraude (haute altitude) [Y: 0 à 64]");
-
- private static final List TEMPERED_ORES = Arrays.asList(
- "Charbon Concentre [Y: 0 à 70]",
- "Fer (stone) [Y: 0 à 100]",
- "Fer (deepslate) [Y: -64 à 0]");
-
- private static final List RARE_ORES = Arrays.asList(
- "Emeraude (basse altitude) [Y: -64 à 0]");
+ private static final List TEMPERATE_ORES = Arrays.asList(
+ "Fer (stone) [Y: 0 a 100]",
+ "Fer (deepslate) [Y: -64 a 0]",
+ "Charbon concentre [Y: 0 a 70]");
private static final List EVERYWHERE_ORES = Arrays.asList(
- "Diamant Shard (deepslate) [Y: -64 à -40]",
- "Bloc Diamant Shard [Y: 0 à 15]");
+ "Diamant Shard (deepslate) [Y: -64 a -40]",
+ "Bloc Diamant Shard [Y: 0 a 15]");
public OreBiomeFinderItem() {
super(new Item.Properties().stacksTo(1));
@@ -68,68 +46,52 @@ public class OreBiomeFinderItem extends Item {
ItemStack stack = player.getItemInHand(hand);
if (!level.isClientSide) {
- BlockPos pos = player.blockPosition();
- var biomeHolder = level.getBiome(pos);
- ResourceKey biomeKey = biomeHolder.unwrapKey()
- .orElse(ResourceKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("minecraft", "plains")));
- ResourceLocation biomeId = biomeKey.location();
- String biomeName = biomeId.getPath();
+ int x = player.blockPosition().getX();
+ int z = player.blockPosition().getZ();
- player.displayClientMessage(Component.literal("=== Minerais dans: " + biomeName + " ==="), false);
- player.displayClientMessage(Component.literal("Biome ID: " + biomeId), false);
+ String zone = LatitudeConfig.zoneName(z);
+ int coldZ = LatitudeConfig.getColdZoneZ();
+ int hotZ = LatitudeConfig.getHotZoneZ();
+ ChatFormatting zoneColor = zoneColor(zone);
- // Vérifier les tags personnalisés du mod
- Set foundTags = new HashSet<>();
- List foundOres = new ArrayList<>();
+ player.displayClientMessage(Component.literal(
+ "=== Position: X=" + x + " Z=" + z + " ===").withStyle(ChatFormatting.GRAY), false);
+ player.displayClientMessage(Component.literal(
+ "Zone determinee par la coordonnee Z : " + zone).withStyle(zoneColor), false);
+ player.displayClientMessage(Component.literal(
+ "Z < " + coldZ + " = froid | " + coldZ + " a " + hotZ + " = tempere | Z > " + hotZ + " = chaud")
+ .withStyle(ChatFormatting.GRAY), false);
- // Vérifier chaque tag de biome et ajouter les minerais correspondants
- if (isBiomeInTag(level, pos, COLD_BIOMES_TAG)) {
- foundTags.add("cold_biomes");
- foundOres.addAll(COLD_ORES);
- }
- if (isBiomeInTag(level, pos, HOT_BIOMES_TAG)) {
- foundTags.add("hot_biomes");
- foundOres.addAll(HOT_ORES);
- }
- if (isBiomeInTag(level, pos, MOUNTAIN_BIOMES_TAG)) {
- foundTags.add("mountain_biomes");
- foundOres.addAll(MOUNTAIN_ORES);
- }
- if (isBiomeInTag(level, pos, TEMPERED_BIOMES_TAG)) {
- foundTags.add("tempered_biomes");
- foundOres.addAll(TEMPERED_ORES);
- }
- if (isBiomeInTag(level, pos, RARE_BIOMES_TAG)) {
- foundTags.add("rare_biomes");
- foundOres.addAll(RARE_ORES);
+ List zoneOres = new ArrayList<>();
+ switch (zone) {
+ case "COLD" -> zoneOres.addAll(COLD_ORES);
+ case "HOT" -> zoneOres.addAll(HOT_ORES);
+ case "TEMPERATE" -> zoneOres.addAll(TEMPERATE_ORES);
}
- // Ajouter les minerais présents partout
- foundOres.addAll(EVERYWHERE_ORES);
+ Set allOres = new LinkedHashSet<>(zoneOres);
+ allOres.addAll(EVERYWHERE_ORES);
- // Afficher les tags trouvés
- if (!foundTags.isEmpty()) {
- player.displayClientMessage(Component.literal("Tags du mod: " + String.join(", ", foundTags)), false);
- } else {
- player.displayClientMessage(Component.literal("Tags du mod: aucun"), false);
+ player.displayClientMessage(Component.literal(
+ "Minerais trouvables (" + allOres.size() + ") :").withStyle(ChatFormatting.WHITE), false);
+ for (String ore : zoneOres) {
+ player.displayClientMessage(Component.literal(" * " + ore).withStyle(zoneColor), false);
}
-
- // Afficher les minerais (sans doublons)
- if (!foundOres.isEmpty()) {
- Set uniqueOres = new LinkedHashSet<>(foundOres);
- player.displayClientMessage(Component.literal("Minerais trouvables:"), false);
- for (String ore : uniqueOres) {
- player.displayClientMessage(Component.literal(" * " + ore), false);
- }
- } else {
- player.displayClientMessage(Component.literal("Aucun minerai specifique"), false);
+ for (String ore : EVERYWHERE_ORES) {
+ player.displayClientMessage(Component.literal(" * " + ore)
+ .withStyle(ChatFormatting.LIGHT_PURPLE), false);
}
}
return InteractionResultHolder.sidedSuccess(stack, level.isClientSide);
}
- private static boolean isBiomeInTag(Level level, BlockPos pos, TagKey tag) {
- return level.getBiome(pos).is(tag);
+ private static ChatFormatting zoneColor(String zone) {
+ return switch (zone) {
+ case "COLD" -> ChatFormatting.AQUA;
+ case "HOT" -> ChatFormatting.GOLD;
+ case "TEMPERATE" -> ChatFormatting.GREEN;
+ default -> ChatFormatting.WHITE;
+ };
}
}
diff --git a/src/main/java/net/mcreator/customoregen/mixin/MultiNoiseBiomeSourceMixin.java b/src/main/java/net/mcreator/customoregen/mixin/MultiNoiseBiomeSourceMixin.java
new file mode 100644
index 00000000..45593190
--- /dev/null
+++ b/src/main/java/net/mcreator/customoregen/mixin/MultiNoiseBiomeSourceMixin.java
@@ -0,0 +1,91 @@
+package net.mcreator.customoregen.mixin;
+
+import com.mojang.datafixers.util.Pair;
+import net.minecraft.core.Holder;
+import net.minecraft.world.level.biome.Biome;
+import net.minecraft.world.level.biome.Biomes;
+import net.minecraft.world.level.biome.Climate;
+import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
+import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+import java.util.Optional;
+
+/**
+ * Makes the Deep Dark a legendary northern-only feature.
+ *
+ * Vanilla places Deep Dark based on depth alone, appearing everywhere underground. This mixin
+ * intercepts biome resolution: when vanilla selects Deep Dark outside cold latitudes
+ * (temperature > -0.3), it brute-force searches the parameter list for the best non-Deep-Dark
+ * biome using the same fitness function as vanilla (sum of squared parameter distances).
+ */
+@Mixin(MultiNoiseBiomeSource.class)
+public abstract class MultiNoiseBiomeSourceMixin {
+
+ @Shadow
+ @Final
+ private com.mojang.datafixers.util.Either>, Holder> parameters;
+
+ @Inject(method = "getNoiseBiome(Lnet/minecraft/world/level/biome/Climate$TargetPoint;)Lnet/minecraft/core/Holder;",
+ at = @At("RETURN"), cancellable = true)
+ private void customoregen$latitudeDeepDarkLock(Climate.TargetPoint target,
+ CallbackInfoReturnable> cir) {
+ Holder original = cir.getReturnValue();
+ if (original == null) return;
+ if (original.unwrapKey().orElse(null) != Biomes.DEEP_DARK) return;
+
+ float temperature = Climate.unquantizeCoord(target.temperature());
+ if (temperature <= -0.3f) return; // Cold zone — keep Deep Dark
+
+ // Warm zone: brute-force search for best non-Deep-Dark biome
+ Climate.ParameterList> paramList = resolveParamList();
+ if (paramList == null) return;
+
+ Holder best = null;
+ long bestFitness = Long.MAX_VALUE;
+ for (Pair> entry : paramList.values()) {
+ if (entry.getSecond().unwrapKey().orElse(null) == Biomes.DEEP_DARK) continue;
+ long fitness = computeFitness(entry.getFirst(), target);
+ if (fitness < bestFitness) {
+ bestFitness = fitness;
+ best = entry.getSecond();
+ }
+ }
+ if (best != null) {
+ cir.setReturnValue(best);
+ }
+ }
+
+ /**
+ * Compute fitness using the same formula as Climate.ParameterPoint.fitness():
+ * fitness = offset + sum of squared parameter distances for temperature, humidity,
+ * continentalness, erosion, depth, weirdness.
+ */
+ private static long computeFitness(Climate.ParameterPoint params, Climate.TargetPoint target) {
+ long tempDist = params.temperature().distance(target.temperature());
+ long humidDist = params.humidity().distance(target.humidity());
+ long contDist = params.continentalness().distance(target.continentalness());
+ long erosDist = params.erosion().distance(target.erosion());
+ long depthDist = params.depth().distance(target.depth());
+ long weirdDist = params.weirdness().distance(target.weirdness());
+
+ return params.offset()
+ + tempDist * tempDist + humidDist * humidDist + contDist * contDist
+ + erosDist * erosDist + depthDist * depthDist + weirdDist * weirdDist;
+ }
+
+ private Climate.ParameterList> resolveParamList() {
+ Optional>> left = parameters.left();
+ if (left.isPresent()) return left.get();
+ Optional> right = parameters.right();
+ if (right.isPresent() && right.get().isBound()) {
+ return right.get().value().parameters();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/BiomeBand.java b/src/main/java/net/mcreator/customoregen/worldgen/BiomeBand.java
deleted file mode 100644
index 63be6e17..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/BiomeBand.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderGetter;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.tags.TagKey;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.biome.Biomes;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Latitude climate bands used by {@link LatitudeBiomeSource}.
- *
- * The world is split along the Z axis (latitude) into climate bands:
- * the far north is frozen, the equator is temperate, and the far south is hot.
- * Surface biomes are selected from dedicated climate tags (so optional mods such
- * as Biomes O' Plenty are supported gracefully). Ocean and underground (cave) pools
- * are vanilla-only and resolved eagerly because those biomes always exist.
- */
-public enum BiomeBand {
- FROZEN(-1.0),
- COLD(-0.5),
- TEMPERATE(0.0),
- WARM(0.5),
- HOT(1.0);
-
- /** Mid-temperature of the band, in [-1.0, 1.0]. */
- public final double centerTemperature;
-
- BiomeBand(double centerTemperature) {
- this.centerTemperature = centerTemperature;
- }
-
- public static BiomeBand fromTemperature(double temperature) {
- if (temperature <= -0.7) return FROZEN;
- if (temperature <= -0.25) return COLD;
- if (temperature < 0.25) return TEMPERATE;
- if (temperature < 0.7) return WARM;
- return HOT;
- }
-
- /** Surface biome tag for this band (vanilla + optional Biomes O' Plenty). */
- public TagKey surfaceTag() {
- switch (this) {
- case FROZEN:
- case COLD:
- return tag("latitude_cold_surface");
- case TEMPERATE:
- return tag("latitude_temperate_surface");
- case WARM:
- case HOT:
- return tag("latitude_hot_surface");
- default:
- return tag("latitude_temperate_surface");
- }
- }
-
- /**
- * Vanilla surface biomes, used to declare {@code possibleBiomes} safely during worldgen
- * data loading. The full (mod-aware) surface pool is resolved lazily from {@link #surfaceTag()}.
- */
- public List> surfaceVanilla() {
- switch (this) {
- case FROZEN:
- return List.of(
- Biomes.SNOWY_PLAINS, Biomes.ICE_SPIKES, Biomes.SNOWY_TAIGA,
- Biomes.GROVE, Biomes.SNOWY_SLOPES, Biomes.JAGGED_PEAKS, Biomes.FROZEN_PEAKS
- );
- case COLD:
- return List.of(
- Biomes.TAIGA, Biomes.OLD_GROWTH_PINE_TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA,
- Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_GRAVELLY_HILLS,
- Biomes.GROVE, Biomes.SNOWY_SLOPES
- );
- case TEMPERATE:
- return List.of(
- Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST,
- Biomes.OLD_GROWTH_BIRCH_FOREST, Biomes.DARK_FOREST, Biomes.FLOWER_FOREST,
- Biomes.SWAMP, Biomes.MEADOW, Biomes.CHERRY_GROVE
- );
- case WARM:
- return List.of(
- Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.WINDSWEPT_SAVANNA,
- Biomes.BIRCH_FOREST, Biomes.FOREST, Biomes.PLAINS, Biomes.MEADOW
- );
- case HOT:
- return List.of(
- Biomes.DESERT, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS,
- Biomes.SAVANNA, Biomes.JUNGLE, Biomes.SPARSE_JUNGLE, Biomes.BAMBOO_JUNGLE,
- Biomes.MANGROVE_SWAMP
- );
- default:
- return List.of(Biomes.PLAINS);
- }
- }
-
- public List> ocean() {
- switch (this) {
- case FROZEN:
- return List.of(Biomes.FROZEN_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.FROZEN_RIVER);
- case COLD:
- return List.of(Biomes.COLD_OCEAN, Biomes.DEEP_COLD_OCEAN);
- case TEMPERATE:
- return List.of(Biomes.OCEAN, Biomes.DEEP_OCEAN, Biomes.RIVER);
- case WARM:
- return List.of(Biomes.LUKEWARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN);
- case HOT:
- return List.of(Biomes.WARM_OCEAN);
- default:
- return List.of(Biomes.OCEAN);
- }
- }
-
- /** Resolve a list of (possibly absent) biome keys into actual holders, skipping missing ones. */
- public static List> resolve(HolderGetter getter, List> keys) {
- List> holders = new ArrayList<>();
- for (ResourceKey key : keys) {
- getter.get(key).ifPresent(holders::add);
- }
- return holders;
- }
-
- private static TagKey tag(String name) {
- return TagKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("custom_ore_gen", name));
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeBiomeSource.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeBiomeSource.java
deleted file mode 100644
index a119c1ce..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeBiomeSource.java
+++ /dev/null
@@ -1,356 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import com.mojang.serialization.Codec;
-import com.mojang.serialization.MapCodec;
-import com.mojang.serialization.codecs.RecordCodecBuilder;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderGetter;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.RegistryOps;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.biome.BiomeSource;
-import net.minecraft.world.level.biome.Biomes;
-import net.minecraft.world.level.biome.Climate;
-import net.minecraft.world.level.levelgen.synth.ImprovedNoise;
-
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Stream;
-
-/**
- * Custom {@link BiomeSource} that distributes biomes by latitude (Z axis).
- *
- *
- * - Far north (large negative Z) = frozen / cold biomes
- * - Equator (Z ≈ 0) = temperate biomes
- * - Far south (large positive Z) = hot biomes
- *
- *
- * Temperature is derived from the Z coordinate with a gentle boundary perturbation so the
- * climate bands are not perfectly straight lines. Inside each band, a very low-frequency
- * selector noise picks among the band's biomes, producing extremely large biomes that
- * encourage exploration and long-distance travel (railways, roads, nether hubs).
- *
- * Underground philosophy: the surface latitude biome extends downward by default, so
- * mining under a desert feels like being in the desert. Cave biomes (lush / dripstone) only
- * appear as rare climatic pockets in the mid underground, and the Deep Dark is a legendary
- * (~1%) feature of the deep zone. This keeps the latitude logic coherent at every depth
- * instead of overriding it with a uniform cave-biome slab.
- *
- * Surface biomes come from dedicated climate tags (see {@code data/custom_ore_gen/tags/
- * worldgen/biome/latitude_*_surface.json}), which support optional Biomes O' Plenty biomes
- * via {@code "required": false} without ever creating unbound holders. Ocean pools are
- * vanilla-only.
- */
-public class LatitudeBiomeSource extends BiomeSource {
-
- public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
- Codec.LONG.fieldOf("seed").forGetter(src -> src.seed),
- RegistryOps.retrieveGetter(Registries.BIOME)
- ).apply(instance, instance.stable(LatitudeBiomeSource::new)));
-
- // ------------------------------------------------------------------
- // Surface / climate tunables
- // ------------------------------------------------------------------
-
- /** Number of blocks for the temperature to go from 0 (equator) to +-1 (pole). */
- private static final double TEMPERATURE_SCALE = LatitudeMath.TEMPERATURE_SCALE;
-
- /** Noise frequency for the climate band boundary wobble. */
- private static final double BOUNDARY_NOISE_SCALE = LatitudeMath.BOUNDARY_NOISE_SCALE;
-
- /** Amplitude of the boundary wobble (in temperature units). */
- private static final double BOUNDARY_NOISE_AMPLITUDE = LatitudeMath.BOUNDARY_NOISE_AMPLITUDE;
-
- /** Selector noise frequency for surface sub-biomes (very low = very large biomes). */
- private static final double SURFACE_SELECTOR_SCALE = LatitudeMath.SURFACE_SELECTOR_SCALE;
-
- /** Frequency of the land/ocean mask noise. */
- private static final double OCEAN_NOISE_SCALE = LatitudeMath.OCEAN_NOISE_SCALE;
-
- /** Above this ocean-noise value, the column is ocean. */
- private static final double OCEAN_THRESHOLD = LatitudeMath.OCEAN_THRESHOLD;
-
- /** Frequency of the moisture noise that carves rare swamp/mangrove pockets. */
- private static final double MOISTURE_SCALE = LatitudeMath.MOISTURE_SCALE;
-
- /** Above this moisture value a wet biome (swamp/mangrove) overrides the surface. ~8% of land. */
- private static final double MOISTURE_THRESHOLD = LatitudeMath.MOISTURE_THRESHOLD;
-
- // ------------------------------------------------------------------
- // Underground tunables (3-zone model)
- // ------------------------------------------------------------------
-
- /** Top of the deep zone (Y < this = deep underground). Deep Dark can live here. */
- private static final int DEEP_ZONE_TOP = LatitudeMath.DEEP_ZONE_TOP;
-
- /** Top of the mid-cave zone (DEEP_ZONE_TOP ≤ Y < this = mid caves, lush/dripstone pockets). */
- private static final int MID_CAVE_TOP = LatitudeMath.MID_CAVE_TOP;
-
- /** Frequency of the mid-cave pocket noise (lush/dripstone). */
- private static final double CAVE_SCALE = LatitudeMath.CAVE_SCALE;
-
- /** Above this value a lush/dripstone pocket overrides the surface biome. ~5-8% of the mid zone. */
- private static final double CAVE_THRESHOLD = LatitudeMath.CAVE_THRESHOLD;
-
- /** Frequency of the Deep Dark noise (very low = large, rare regions). */
- private static final double DEEP_DARK_SCALE = LatitudeMath.DEEP_DARK_SCALE;
-
- /** Vertical frequency of the Deep Dark noise (keeps it coherent in tall sections). */
- private static final double DEEP_DARK_SCALE_Y = LatitudeMath.DEEP_DARK_SCALE_Y;
-
- /** Above this value the Deep Dark overrides. Tuned for ~1-2% of the deep zone (legendary). */
- private static final double DEEP_DARK_THRESHOLD = LatitudeMath.DEEP_DARK_THRESHOLD;
-
- // ------------------------------------------------------------------
- // Spawn safe zone
- // ------------------------------------------------------------------
-
- /** Half-size of the guaranteed safe spawn square around the origin (plains/forest). */
- private static final int SPAWN_SAFE_RADIUS = LatitudeMath.SPAWN_SAFE_RADIUS;
-
- /** Selector frequency inside the spawn safe zone (finer, for gentle variety). */
- private static final double SPAWN_SELECTOR_SCALE = LatitudeMath.SPAWN_SELECTOR_SCALE;
-
- // ------------------------------------------------------------------
- // Fields
- // ------------------------------------------------------------------
-
- private final long seed;
- private final HolderGetter biomeGetter;
-
- private final ImprovedNoise boundaryNoise;
- private final ImprovedNoise selectorNoise;
- private final ImprovedNoise oceanNoise;
- private final ImprovedNoise moistureNoise;
- private final ImprovedNoise caveNoise;
- private final ImprovedNoise deepDarkNoise;
-
- /** Vanilla-only pools resolved eagerly (safe: vanilla biomes always exist and are bound). */
- private final EnumMap resolvedVanilla;
- private final Set> possibleBiomes;
- private final Holder fallback;
-
- /** Safe spawn pool (plains / forests) resolved eagerly. Always near the origin. */
- private final List> spawnSafeBiomes;
-
- /** Rare wet biomes (swamp = temperate, mangrove = warm/hot), placed by moisture noise. */
- private final Holder swampBiome;
- private final Holder mangroveBiome;
-
- /** Cave biomes resolved eagerly (vanilla, always present). Lush = humid bands, Dripstone = dry bands. */
- private final Holder lushCavesBiome;
- private final Holder dripstoneCavesBiome;
- private final Holder deepDarkBiome;
-
- /** Mod-aware surface pools resolved lazily from climate tags (safe: tags are bound by then). */
- private volatile EnumMap>> surfaceFromTag;
-
- public LatitudeBiomeSource(long seed, HolderGetter biomeGetter) {
- this.seed = seed;
- this.biomeGetter = biomeGetter;
-
- RandomSource rng = RandomSource.create(seed);
- this.boundaryNoise = new ImprovedNoise(rng);
- this.selectorNoise = new ImprovedNoise(RandomSource.create(seed ^ 0x4C415449L));
- this.oceanNoise = new ImprovedNoise(RandomSource.create(seed ^ 0x4F434541L));
- this.moistureNoise = new ImprovedNoise(RandomSource.create(seed ^ 0x57455421L));
- this.caveNoise = new ImprovedNoise(RandomSource.create(seed ^ 0x43415645L));
- this.deepDarkNoise = new ImprovedNoise(RandomSource.create(seed ^ 0x44454550L));
-
- this.resolvedVanilla = new EnumMap<>(BiomeBand.class);
- Set> all = new HashSet<>();
- for (BiomeBand band : BiomeBand.values()) {
- List> surface = BiomeBand.resolve(biomeGetter, band.surfaceVanilla());
- List> ocean = BiomeBand.resolve(biomeGetter, band.ocean());
-
- resolvedVanilla.put(band, new ResolvedBand(surface, ocean));
- all.addAll(surface);
- all.addAll(ocean);
- }
-
- // Cave biomes (vanilla) declared so the source advertises them as possible.
- this.lushCavesBiome = resolveAndAdd(biomeGetter, Biomes.LUSH_CAVES, all);
- this.dripstoneCavesBiome = resolveAndAdd(biomeGetter, Biomes.DRIPSTONE_CAVES, all);
- this.deepDarkBiome = resolveAndAdd(biomeGetter, Biomes.DEEP_DARK, all);
-
- this.possibleBiomes = all;
-
- List> safe = new ArrayList<>();
- safe.addAll(BiomeBand.resolve(biomeGetter, List.of(
- Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS,
- Biomes.FOREST, Biomes.BIRCH_FOREST, Biomes.FLOWER_FOREST,
- Biomes.MEADOW
- )));
- this.spawnSafeBiomes = safe.isEmpty() ? null : safe;
-
- this.swampBiome = biomeGetter.get(Biomes.SWAMP).orElse(null);
- this.mangroveBiome = biomeGetter.get(Biomes.MANGROVE_SWAMP).orElse(null);
-
- Holder plains = biomeGetter.get(Biomes.PLAINS).orElse(null);
- this.fallback = plains != null ? plains : (possibleBiomes.isEmpty() ? null : possibleBiomes.iterator().next());
- }
-
- private static Holder resolveAndAdd(HolderGetter getter, net.minecraft.resources.ResourceKey key, Set> into) {
- Holder holder = getter.get(key).orElse(null);
- if (holder != null) {
- into.add(holder);
- }
- return holder;
- }
-
- @Override
- protected MapCodec extends BiomeSource> codec() {
- return CODEC;
- }
-
- @Override
- protected Stream> collectPossibleBiomes() {
- return possibleBiomes.stream();
- }
-
- @Override
- public Holder getNoiseBiome(int quartX, int quartY, int quartZ, Climate.Sampler sampler) {
- int blockX = quartX * 4;
- int blockZ = quartZ * 4;
- int blockY = quartY * 4;
-
- double latitudeTemp = blockZ / TEMPERATURE_SCALE;
- double wobble = boundaryNoise.noise(blockX * BOUNDARY_NOISE_SCALE, 0.0, blockZ * BOUNDARY_NOISE_SCALE) * BOUNDARY_NOISE_AMPLITUDE;
- double temperature = clamp(latitudeTemp + wobble, -1.0, 1.0);
-
- BiomeBand band = BiomeBand.fromTemperature(temperature);
- ResolvedBand pool = resolvedVanilla.get(band);
- if (pool == null) {
- pool = resolvedVanilla.get(BiomeBand.TEMPERATE);
- }
-
- // Guaranteed safe spawn zone (open, buildable biomes) around the origin.
- if (spawnSafeBiomes != null && LatitudeMath.isInSpawnSafeZone(blockX, blockZ)) {
- return pickBiome(spawnSafeBiomes, blockX, blockZ, SPAWN_SELECTOR_SCALE);
- }
-
- // Determine the column's base biome: ocean mask, rare wet pocket, or latitude surface biome.
- Holder base = baseSurfaceBiome(band, pool, blockX, blockZ);
-
- // Underground cave overrides (3-zone model) extend latitude rather than replace it.
- return applyCaveOverrides(base, band, blockX, blockY, blockZ);
- }
-
- /** Resolve the surface biome for a column: ocean, swamp/mangrove pocket, or the band's surface tag. */
- private Holder baseSurfaceBiome(BiomeBand band, ResolvedBand pool, int blockX, int blockZ) {
- double oceanValue = oceanNoise.noise(blockX * OCEAN_NOISE_SCALE, 0.0, blockZ * OCEAN_NOISE_SCALE);
- if (oceanValue > OCEAN_THRESHOLD && !pool.ocean().isEmpty()) {
- return pickBiome(pool.ocean(), blockX, blockZ, 0.002);
- }
-
- double moisture = moistureNoise.noise(blockX * MOISTURE_SCALE, 0.0, blockZ * MOISTURE_SCALE);
- if (moisture > MOISTURE_THRESHOLD) {
- if (band == BiomeBand.TEMPERATE && swampBiome != null) {
- return swampBiome;
- }
- if ((band == BiomeBand.WARM || band == BiomeBand.HOT) && mangroveBiome != null) {
- return mangroveBiome;
- }
- }
-
- List> surface = resolveSurfaceTag(band);
- if (surface == null || surface.isEmpty()) {
- surface = pool.surface();
- if (surface.isEmpty()) {
- surface = resolvedVanilla.get(BiomeBand.TEMPERATE).surface();
- }
- }
- return pickBiome(surface, blockX, blockZ, SURFACE_SELECTOR_SCALE);
- }
-
- /**
- * Underground overrides keep the latitude biome by default and only carve rare cave features:
- *
- * - Deep zone (Y < {@value #DEEP_ZONE_TOP}): legendary Deep Dark pockets (~1%), else surface biome.
- * - Mid caves (DEEP_ZONE_TOP ≤ Y < {@value #MID_CAVE_TOP}): lush/dripstone pockets (~8%) matching the climate.
- * - Near surface: no override, latitude biome as-is.
- *
- */
- private Holder applyCaveOverrides(Holder surfaceBiome, BiomeBand band, int blockX, int blockY, int blockZ) {
- LatitudeMath.Zone zone = LatitudeMath.zoneForY(blockY);
- // Deep zone: legendary Deep Dark.
- if (zone == LatitudeMath.Zone.DEEP) {
- if (deepDarkBiome != null) {
- double dd = deepDarkNoise.noise(blockX * DEEP_DARK_SCALE, blockY * DEEP_DARK_SCALE_Y, blockZ * DEEP_DARK_SCALE);
- if (LatitudeMath.isDeepDarkPocket(dd)) {
- return deepDarkBiome;
- }
- }
- return surfaceBiome;
- }
-
- // Mid caves: rare lush/dripstone pockets by climate.
- if (zone == LatitudeMath.Zone.MID_CAVE) {
- Holder caveBiome = caveBiomeFor(band);
- if (caveBiome != null) {
- double cave = caveNoise.noise(blockX * CAVE_SCALE, 0.0, blockZ * CAVE_SCALE);
- if (LatitudeMath.isMidCavePocket(cave)) {
- return caveBiome;
- }
- }
- }
-
- return surfaceBiome;
- }
-
- /** Lush caves for humid/warm bands, dripstone for dry/cold bands. */
- private Holder caveBiomeFor(BiomeBand band) {
- if (band == BiomeBand.FROZEN || band == BiomeBand.COLD) {
- return dripstoneCavesBiome;
- }
- return lushCavesBiome;
- }
-
- /** Lazily resolve surface biomes from climate tags. Tags are bound after the registry freezes,
- * so this is safe and never creates unbound holders. */
- private List> resolveSurfaceTag(BiomeBand band) {
- EnumMap>> cache = surfaceFromTag;
- if (cache != null) {
- return cache.get(band);
- }
- synchronized (this) {
- if (surfaceFromTag == null) {
- EnumMap>> built = new EnumMap<>(BiomeBand.class);
- for (BiomeBand b : BiomeBand.values()) {
- List> holders = new ArrayList<>();
- biomeGetter.get(b.surfaceTag()).map(HolderSet::stream).ifPresent(stream -> stream.forEach(holders::add));
- built.put(b, holders);
- }
- surfaceFromTag = built;
- }
- return surfaceFromTag.get(band);
- }
- }
-
- private Holder pickBiome(List> biomes, int blockX, int blockZ, double scale) {
- if (biomes == null || biomes.isEmpty()) {
- return fallback;
- }
- // Dual-octave noise for a flatter, near-uniform index distribution: a single ImprovedNoise
- // value is bell-curved around 0, which makes the middle of the biome list dominate. Adding a
- // second octave at an offset flattens the curve so no biome is disproportionately common.
- double n1 = selectorNoise.noise(blockX * scale, blockZ * scale, 1000.0);
- double n2 = selectorNoise.noise(blockX * scale * 1.9 + 137.0, blockZ * scale * 1.9 - 211.0, 2000.0);
- double normalized = LatitudeMath.normalisedSelector(n1, n2);
- int idx = LatitudeMath.selectorIndex(normalized, biomes.size());
- return biomes.get(idx);
- }
-
- private static double clamp(double value, double min, double max) {
- return value < min ? min : (value > max ? max : value);
- }
-
- private record ResolvedBand(List> surface, List> ocean) {
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeConfig.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeConfig.java
new file mode 100644
index 00000000..dacbe6b7
--- /dev/null
+++ b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeConfig.java
@@ -0,0 +1,57 @@
+package net.mcreator.customoregen.worldgen;
+
+import net.mcreator.customoregen.config.ModConfigs;
+
+/**
+ * Runtime accessor for the latitude zone thresholds.
+ *
+ * These values come from the mod's config file and control both the ore distribution (which Z
+ * coordinates get which ores) and the temperature latitude scale. Changing them at runtime (via
+ * the config file) shifts both the ore zones and the climate bands simultaneously.
+ *
+ * Defaults:
+ *
+ * - {@code coldZoneZ = -8000}: north of Z=-8000 is the cold zone
+ * - {@code hotZoneZ = 8000}: south of Z=8000 is the hot zone
+ * - Between -8000 and 8000 is the temperate zone (16,000 blocks wide)
+ *
+ *
+ */
+public final class LatitudeConfig {
+
+ private LatitudeConfig() {}
+
+ private static int coldZoneZ = -8000;
+ private static int hotZoneZ = 8000;
+
+ /** Z threshold below which is the cold zone. Negative = north. */
+ public static int getColdZoneZ() {
+ try {
+ return net.mcreator.customoregen.config.ModConfigs.LATITUDE_ORE.coldZoneZ.get();
+ } catch (Exception e) {
+ return coldZoneZ;
+ }
+ }
+
+ /** Z threshold above which is the hot zone. Positive = south. */
+ public static int getHotZoneZ() {
+ try {
+ return net.mcreator.customoregen.config.ModConfigs.LATITUDE_ORE.hotZoneZ.get();
+ } catch (Exception e) {
+ return hotZoneZ;
+ }
+ }
+
+ /** Called from the config load to update thresholds. */
+ public static void update(int coldZ, int hotZ) {
+ coldZoneZ = coldZ;
+ hotZoneZ = hotZ;
+ }
+
+ /** Returns a human-readable description of the zone for a given Z. */
+ public static String zoneName(int z) {
+ if (z < getColdZoneZ()) return "COLD";
+ if (z > getHotZoneZ()) return "HOT";
+ return "TEMPERATE";
+ }
+}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeGameTest.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeGameTest.java
deleted file mode 100644
index 520ecbb4..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeGameTest.java
+++ /dev/null
@@ -1,518 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import net.mcreator.customoregen.CustomOreGenMod;
-import net.mcreator.customoregen.config.ConfigHelper;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderGetter;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.gametest.framework.GameTest;
-import net.minecraft.gametest.framework.GameTestHelper;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.biome.Biomes;
-import net.neoforged.neoforge.gametest.GameTestHolder;
-import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Automated world-map validation for the latitude biome system, run as a NeoForge
- * {@link GameTest} so it executes inside a real game server with the full biome registry.
- *
- * Launch with {@code ./gradlew runGameTestServer}. The test samples a large grid through a
- * freshly built {@link LatitudeBiomeSource} at several depths and renders one PNG map per depth
- * (a "geological slice" view), writes a distribution report and asserts the climate + cave
- * invariants. No manual in-game testing required.
- */
-@GameTestHolder(CustomOreGenMod.MODID)
-@PrefixGameTestTemplate(false)
-public class LatitudeGameTest {
-
- private static final int RADIUS = 16000; // covers equator -> pole
- private static final int STEP = 80; // ~400x400 samples
- private static final long SEED = 0L;
- private static final Path OUT_DIR = Path.of("gametest-results", "latitude");
-
- // Sampling depths (one PNG per depth = a top-down "slice").
- private static final int SURFACE_Y = 64;
- private static final int MID_CAVE_Y = -15; // -30 <= Y < 0 (lush/dripstone pockets)
- private static final int DEEP_Y = -50; // Y < -30 (legendary Deep Dark)
-
- private static final Map, Integer> COLORS = new HashMap<>();
-
- static {
- col(0xB6E388, Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST,
- Biomes.FLOWER_FOREST, Biomes.MEADOW, Biomes.CHERRY_GROVE);
- col(0xC8E6FF, Biomes.SNOWY_PLAINS, Biomes.ICE_SPIKES, Biomes.SNOWY_TAIGA, Biomes.GROVE,
- Biomes.SNOWY_SLOPES, Biomes.JAGGED_PEAKS, Biomes.FROZEN_PEAKS, Biomes.FROZEN_OCEAN,
- Biomes.DEEP_FROZEN_OCEAN, Biomes.FROZEN_RIVER);
- col(0x8FB8D6, Biomes.TAIGA, Biomes.OLD_GROWTH_PINE_TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA,
- Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_GRAVELLY_HILLS,
- Biomes.COLD_OCEAN, Biomes.DEEP_COLD_OCEAN);
- col(0x7CC576, Biomes.DARK_FOREST, Biomes.OLD_GROWTH_BIRCH_FOREST, Biomes.RIVER,
- Biomes.OCEAN, Biomes.DEEP_OCEAN);
- col(0xE0C068, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.WINDSWEPT_SAVANNA,
- Biomes.LUKEWARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN);
- col(0xE0884C, Biomes.DESERT, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS,
- Biomes.JUNGLE, Biomes.SPARSE_JUNGLE, Biomes.BAMBOO_JUNGLE, Biomes.WARM_OCEAN);
- col(0x5B7A3A, Biomes.SWAMP);
- col(0x3A5A3A, Biomes.MANGROVE_SWAMP);
- // Cave biomes - distinct colors so the slices are readable.
- col(0x4DB05A, Biomes.LUSH_CAVES); // lush green
- col(0xC8782C, Biomes.DRIPSTONE_CAVES); // stalactite orange-brown
- col(0x0A4D54, Biomes.DEEP_DARK); // dark sculk teal
- }
-
- private static void col(int rgb, ResourceKey... keys) {
- for (ResourceKey k : keys) COLORS.put(k, rgb);
- }
-
- @GameTest(template = "empty_1x1", timeoutTicks = 600)
- public static void latitudeMap(GameTestHelper helper) {
- try {
- runLatitudeValidation(helper);
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("Latitude game test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /**
- * Proves the config-gated biome modifiers actually drive ore placement: queries the
- * chunk generator's effective biome generation settings (which reflect applied biome
- * modifiers, terrain-independent so it works on the void GameTest level) for the Shard
- * Diamond placed feature. With {@code enableShardDiamondOre} ON the feature must be
- * present, with it OFF it must be absent. Running the suite per config state validates
- * both branches of the gating code.
- */
- /**
- * Compares ore feature presence across vanilla and Biomes O' Plenty temperate biomes by
- * querying each biome holder's {@code modifiableBiomeInfo()} (the generation settings after
- * NeoForge applies every biome modifier, including the config-gated ore modifiers).
- *
- * In-game, vanilla plains shows custom iron/coal while BOP biomes (highland, shrubland)
- * show none. This test reproduces the comparison in the registry context to pinpoint
- * whether the config-gated modifiers actually inject ores into BOP biomes' settings.
- */
- @GameTest(template = "empty_1x1", timeoutTicks = 200)
- public static void oreFeaturesAcrossBiomes(GameTestHelper helper) {
- try {
- ServerLevel level = helper.getLevel();
- var biomeRegistry = level.registryAccess().lookupOrThrow(Registries.BIOME);
-
- String[] temperateBiomes = {
- "minecraft:plains", "minecraft:birch_forest", "minecraft:forest",
- "biomesoplenty:shrubland", "biomesoplenty:field", "biomesoplenty:moor",
- "biomesoplenty:grassland", "biomesoplenty:woodland", "biomesoplenty:mediterranean_forest"
- };
-
- StringBuilder report = new StringBuilder("\n=== ORE FEATURE PRESENCE PER BIOME (after biome modifiers) ===\n");
- boolean modifiersApplied = false;
- for (String id : temperateBiomes) {
- var key = net.minecraft.resources.ResourceKey.create(Registries.BIOME,
- net.minecraft.resources.ResourceLocation.parse(id));
- Holder holder = biomeRegistry.get(key).orElse(null);
- if (holder == null) {
- report.append(String.format("%-36s NOT FOUND%n", id));
- continue;
- }
- var genSettings = holder.value().modifiableBiomeInfo().get().generationSettings();
- int totalFeatures = 0;
- java.util.List customOres = new java.util.ArrayList<>();
- for (net.minecraft.core.HolderSet stepSet : genSettings.features()) {
- for (net.minecraft.core.Holder featHolder : stepSet) {
- totalFeatures++;
- var fk = featHolder.unwrapKey();
- if (fk.isPresent() && fk.get().location().getNamespace().equals("custom_ore_gen")) {
- customOres.add(fk.get().location().getPath());
- }
- }
- }
- if (totalFeatures > 0) modifiersApplied = true;
- report.append(String.format("%-36s total=%-4d customOres=[%s]%n",
- id, totalFeatures, String.join(",", customOres)));
- }
-
- CustomOreGenMod.LOGGER.info(report.toString());
-
- if (!modifiersApplied) {
- CustomOreGenMod.LOGGER.info("oreFeaturesAcrossBiomes: biome modifiers not observable in this context "
- + "(void test level). Run against a real latitude world for the decisive comparison.");
- }
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("oreFeaturesAcrossBiomes test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /**
- * Determinism: two {@link LatitudeBiomeSource} instances built with the same seed must
- * return biome holders that resolve to the same biome key at every sampled point.
- * Worldgen is shared work across threads, so equality of biome-by-coord is a hard contract.
- * Also asserts a coarse cross-depth determinism: re-querying the same (x,z) at different Y in
- * the surface zone returns the same biome (latitude surface band does not depend on Y in the
- * zone with no override).
- */
- @GameTest(template = "empty_1x1", timeoutTicks = 400)
- public static void latitudeDeterminism(GameTestHelper helper) {
- try {
- ServerLevel level = helper.getLevel();
- HolderGetter getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource a = new LatitudeBiomeSource(SEED, getter);
- LatitudeBiomeSource b = new LatitudeBiomeSource(SEED, getter);
-
- int mismatches = 0;
- int checked = 0;
- // Sample a coarse grid across the climate range, several Y of the surface zone.
- int[] ys = {SURFACE_Y, SURFACE_Y + 1, 100, 200, 320};
- for (int blockZ = -RADIUS; blockZ <= RADIUS; blockZ += 1000) {
- for (int blockX = -4000; blockX <= 4000; blockX += 1000) {
- for (int y : ys) {
- ResourceKey ka = a.getNoiseBiome(blockX >> 2, y >> 2, blockZ >> 2, null).unwrapKey().orElse(null);
- ResourceKey kb = b.getNoiseBiome(blockX >> 2, y >> 2, blockZ >> 2, null).unwrapKey().orElse(null);
- checked++;
- if (!java.util.Objects.equals(ka, kb)) mismatches++;
- }
- }
- }
- assertTrue(checked > 100, "determinism test must check many points, checked=" + checked);
- assertEquals(0, mismatches,
- "same-seed sources must be identical everywhere, had " + mismatches + " / " + checked + " mismatches");
-
- CustomOreGenMod.LOGGER.info("[latitude-determinism] OK: {} points all identical for seed={}", checked, SEED);
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("latitudeDeterminism test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /**
- * Cave biomes (LUSH_CAVES, DRIPSTONE_CAVES, DEEP_DARK) must never surface: the 3-zone model
- * only injects them underground (Y < 0 for lush/dripstone, Y < -30 for Deep Dark).
- * Sampling the whole surface grid and asserting zero cave biomes protects against a regression
- * that would leak a cave biome to the surface (e.g. a swapped zone boundary).
- */
- @GameTest(template = "empty_1x1", timeoutTicks = 400)
- public static void noCaveBiomeAtSurface(GameTestHelper helper) {
- try {
- ServerLevel level = helper.getLevel();
- HolderGetter getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource source = new LatitudeBiomeSource(SEED, getter);
-
- Set> caveBiomes = Set.of(
- Biomes.LUSH_CAVES, Biomes.DRIPSTONE_CAVES, Biomes.DEEP_DARK);
-
- int surfaceCaveLeaks = 0;
- int checked = 0;
- for (int blockZ = -RADIUS; blockZ <= RADIUS; blockZ += STEP) {
- for (int blockX = -RADIUS; blockX <= RADIUS; blockX += STEP) {
- ResourceKey k = source.getNoiseBiome(blockX >> 2, SURFACE_Y >> 2, blockZ >> 2, null)
- .unwrapKey().orElse(null);
- checked++;
- if (k != null && caveBiomes.contains(k)) surfaceCaveLeaks++;
- }
- }
- assertEquals(0, surfaceCaveLeaks,
- "no cave biome must leak to the surface, found " + surfaceCaveLeaks + " / " + checked);
-
- CustomOreGenMod.LOGGER.info("[no-cave-at-surface] OK: {} surface samples, zero cave leaks", checked);
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("noCaveBiomeAtSurface test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /**
- * Spatial continuity / large-biome property: at the surface, the selector noise has a very
- * low frequency (SURFACE_SELECTOR_SCALE = 0.00033), so neighbouring sample points (80 blocks
- * apart) almost always fall in the same biome. This guards against a regression that would
- * turn the world into per-block noise. We accept that band boundaries and ocean/rare pockets
- * create some transitions, but they must remain rare ((< 25 %).
- */
- @GameTest(template = "empty_1x1", timeoutTicks = 400)
- public static void surfaceBiomeContinuity(GameTestHelper helper) {
- try {
- ServerLevel level = helper.getLevel();
- HolderGetter getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource source = new LatitudeBiomeSource(SEED, getter);
-
- // Sample a single horizontal line across one temperate row (Z near 0, well inside one band)
- // and count how often adjacent samples change biome.
- int transitions = 0;
- ResourceKey prev = null;
- int sampleCount = 200;
- int z = 160; // just south of equator, well inside TEMPERATE band, outside spawn-safe square
- for (int i = 0; i < sampleCount; i++) {
- int x = -8000 + i * 80;
- ResourceKey k = source.getNoiseBiome(x >> 2, SURFACE_Y >> 2, z >> 2, null)
- .unwrapKey().orElse(null);
- if (prev != null && !java.util.Objects.equals(prev, k)) transitions++;
- prev = k;
- }
- // 80-block spacing on a 0.00033-frequency noise: the noise barely moves, so transitions
- // are driven mostly by ocean/rare-pocket edges, not selector turnover.
- double transitionRatio = 100.0 * transitions / (sampleCount - 1);
- assertTrue(transitionRatio < 25.0,
- "surface should have large continuous biomes; transition ratio was "
- + String.format("%.1f%%", transitionRatio) + " across a temperate row");
-
- CustomOreGenMod.LOGGER.info("[surface-continuity] OK: {} transitions / {} samples = {}%",
- transitions, sampleCount - 1, String.format("%.1f", transitionRatio));
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("surfaceBiomeContinuity test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /**
- * Progressive climate transition: the surface biome must be predominantly cold at the far
- * north, predominantly temperate at the equator, and predominantly hot at the far south.
- * This is a finer-grained version of the band-ratio assertions in {@link #latitudeMap},
- * checking the gradient direction in three Z windows rather than just the two poles.
- */
- @GameTest(template = "empty_1x1", timeoutTicks = 400)
- public static void climateGradient(GameTestHelper helper) {
- try {
- ServerLevel level = helper.getLevel();
- HolderGetter getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource source = new LatitudeBiomeSource(SEED, getter);
-
- Set> cold = resolveTagKeys(getter, BiomeBand.COLD.surfaceTag());
- Set> coldOceans = new HashSet<>(List.of(
- Biomes.FROZEN_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.COLD_OCEAN, Biomes.DEEP_COLD_OCEAN, Biomes.FROZEN_RIVER));
- cold.addAll(coldOceans);
-
- Set> hot = resolveTagKeys(getter, BiomeBand.HOT.surfaceTag());
- Set> hotOceans = new HashSet<>(List.of(
- Biomes.WARM_OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN, Biomes.MANGROVE_SWAMP));
- hot.addAll(hotOceans);
-
- // Three Z windows, 3200 blocks wide, 800 apart (RADIUS=16000 covers them all).
- assertEquals(5, BiomeBand.values().length, "exactly five climate bands expected");
- double north = windowBiomeRatio(source, -15000, -11800, cold);
- double equator = windowBiomeRatio(source, -1600, 1600, cold); // equator is NOT cold
- double south = windowBiomeRatio(source, 11800, 15000, hot);
-
- assertTrue(north > 50.0, "far north must be >50% cold, was " + String.format("%.1f%%", north));
- double equatorCold = windowBiomeRatio(source, -1600, 1600, cold);
- assertTrue(equatorCold < 25.0,
- "equator must NOT be predominantly cold (gradient broken), was " + String.format("%.1f%%", equatorCold));
- assertTrue(south > 50.0, "far south must be >50% hot, was " + String.format("%.1f%%", south));
-
- CustomOreGenMod.LOGGER.info("[climate-gradient] OK: north(cold)={}%, south(hot)={}%, equator(cold)={}%",
- String.format("%.0f", north), String.format("%.0f", south), String.format("%.0f", equatorCold));
- helper.succeed();
- } catch (AssertionError | Exception e) {
- CustomOreGenMod.LOGGER.error("climateGradient test failed", e);
- helper.fail(e.getMessage());
- }
- }
-
- /** Sample a Z window of the surface and return the % of biomes in the expected set. */
- private static double windowBiomeRatio(LatitudeBiomeSource source, int zMin, int zMax,
- Set> expected) {
- int match = 0;
- int total = 0;
- for (int z = zMin; z <= zMax; z += 160) {
- for (int x = -4000; x <= 4000; x += 800) {
- ResourceKey k = source.getNoiseBiome(x >> 2, SURFACE_Y >> 2, z >> 2, null)
- .unwrapKey().orElse(null);
- total++;
- if (k != null && expected.contains(k)) match++;
- }
- }
- return total == 0 ? 0 : 100.0 * match / total;
- }
-
- private static void runLatitudeValidation(GameTestHelper helper) throws Exception {
- ServerLevel level = helper.getLevel();
- HolderGetter getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource source = new LatitudeBiomeSource(SEED, getter);
-
- Files.createDirectories(OUT_DIR);
-
- // ---- Sample one slice per depth. Each slice produces a PNG + a biome-count map. ----
- Slice surface = sampleSlice(source, SURFACE_Y, "latitude_map_surface.png");
- Slice midCave = sampleSlice(source, MID_CAVE_Y, "latitude_map_mid_cave.png");
- Slice deep = sampleSlice(source, DEEP_Y, "latitude_map_deep.png");
-
- // ---- Surface climate assertions ----
- ResourceKey spawnKey = source.getNoiseBiome(0, SURFACE_Y >> 2, 0, null).unwrapKey().orElse(null);
-
- Set> coldTag = resolveTagKeys(getter, BiomeBand.COLD.surfaceTag());
- Set> hotTag = resolveTagKeys(getter, BiomeBand.HOT.surfaceTag());
- Set> coldOceans = new HashSet<>(List.of(
- Biomes.FROZEN_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.COLD_OCEAN, Biomes.DEEP_COLD_OCEAN,
- Biomes.FROZEN_RIVER));
- Set> hotOceans = new HashSet<>(List.of(
- Biomes.WARM_OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN));
-
- assertNotNull(spawnKey, "spawn biome resolved");
- assertTrue(isSafeSpawn(spawnKey), "spawn must be a safe biome, was " + spawnKey);
-
- Set> northExpected = new HashSet<>();
- northExpected.addAll(coldTag);
- northExpected.addAll(coldOceans);
- double north = sliceBandRatio(surface, BiomeBand.FROZEN, northExpected);
- assertTrue(north > 60.0, "FROZEN band should be >60%% cold/frozen (by tag), was %.1f%%".formatted(north));
-
- Set> southExpected = new HashSet<>();
- southExpected.addAll(hotTag);
- southExpected.addAll(hotOceans);
- southExpected.add(Biomes.MANGROVE_SWAMP);
- double south = sliceBandRatio(surface, BiomeBand.HOT, southExpected);
- assertTrue(south > 60.0, "HOT band should be >60%% warm/hot (by tag), was %.1f%%".formatted(south));
-
- // Swamp stays rare at the surface in the temperate band.
- double swampRatio = biomeRatioInBand(surface, BiomeBand.TEMPERATE, Biomes.SWAMP);
- assertTrue(swampRatio < 15.0, "swamp must be <15%% of temperate band, was %.2f%%".formatted(swampRatio));
-
- // ---- Cave assertions ----
- // Deep Dark is legendary: a small fraction of the deep slice only.
- double deepDarkRatio = biomeRatio(deep, Biomes.DEEP_DARK);
- assertTrue(deepDarkRatio < 8.0,
- "Deep Dark must be rare in the deep zone (<8%%), was %.2f%%".formatted(deepDarkRatio));
-
- // Cave biomes (lush/dripstone) should be a minority even in the mid-cave slice - the latitude
- // biome dominates underground by design.
- double caveBiomeRatio = biomeRatio(midCave, Biomes.LUSH_CAVES, Biomes.DRIPSTONE_CAVES);
- assertTrue(caveBiomeRatio < 25.0,
- "cave biomes must stay a minority in mid-cave (<25%%), was %.2f%%".formatted(caveBiomeRatio));
-
- // ---- Report ----
- StringBuilder r = new StringBuilder();
- r.append("Latitude GameTest Report (seed=").append(SEED).append(")\n\n");
- r.append("Spawn @ (0,0): ").append(spawnKey).append("\n\n");
-
- r.append("=== Depth slices (PNG) ===\n");
- r.append(String.format(" Surface Y=%3d : latitude_map_surface.png%n", SURFACE_Y));
- r.append(String.format(" Mid cave Y=%3d: latitude_map_mid_cave.png%n", MID_CAVE_Y));
- r.append(String.format(" Deep Y=%3d : latitude_map_deep.png%n%n", DEEP_Y));
-
- r.append("=== Surface top biomes (top 12) ===\n");
- appendTop(r, surface.global, 12);
-
- r.append("\n=== Mid cave (Y=").append(MID_CAVE_Y).append(") top biomes (top 10) ===\n");
- appendTop(r, midCave.global, 10);
-
- r.append("\n=== Deep (Y=").append(DEEP_Y).append(") top biomes (top 10) ===\n");
- appendTop(r, deep.global, 10);
-
- Files.writeString(OUT_DIR.resolve("latitude_report.txt"), r.toString());
-
- // ---- One-line summary ----
- CustomOreGenMod.LOGGER.info(String.format(
- "Latitude game test OK: spawn=%s | north=%.0f%% | south=%.0f%% | swamp=%.2f%% | "
- + "deepDark=%.2f%% | caveBiomes=%.1f%%",
- spawnKey, north, south, swampRatio, deepDarkRatio, caveBiomeRatio));
- }
-
- /** Sample the whole grid at a single Y and write a PNG; returns the slice's biome counts. */
- private static Slice sampleSlice(LatitudeBiomeSource source, int blockY, String pngName) throws Exception {
- int dim = (2 * RADIUS) / STEP + 1;
- BufferedImage img = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_RGB);
- Map, Integer> global = new HashMap<>();
- Map, Integer>> perBand = new EnumMap<>(BiomeBand.class);
- for (BiomeBand b : BiomeBand.values()) perBand.put(b, new HashMap<>());
-
- for (int zi = 0; zi < dim; zi++) {
- for (int xi = 0; xi < dim; xi++) {
- int blockX = -RADIUS + xi * STEP;
- int blockZ = -RADIUS + zi * STEP;
- Holder holder = source.getNoiseBiome(blockX >> 2, blockY >> 2, blockZ >> 2, null);
- ResourceKey key = holder.unwrapKey().orElse(null);
-
- global.merge(key, 1, Integer::sum);
- perBand.get(BiomeBand.fromTemperature(blockZ / 16000.0)).merge(key, 1, Integer::sum);
-
- int rgb = key == null ? 0x888888 : COLORS.getOrDefault(key, 0x888888);
- img.setRGB(xi, dim - 1 - zi, rgb); // flip Z so north is at the top
- }
- }
- ImageIO.write(img, "png", OUT_DIR.resolve(pngName).toFile());
- return new Slice(global, perBand);
- }
-
- private static void appendTop(StringBuilder r, Map, Integer> counts, int limit) {
- int total = counts.values().stream().mapToInt(Integer::intValue).sum();
- counts.entrySet().stream()
- .sorted(Map.Entry., Integer>comparingByValue().reversed())
- .limit(limit)
- .forEach(e -> r.append(String.format(" %-45s %6.2f%%%n", e.getKey(), 100.0 * e.getValue() / total)));
- }
-
- /** Ratio of a set of biomes within a single band of a slice. */
- private static double sliceBandRatio(Slice slice, BiomeBand band, Set> expected) {
- Map, Integer> m = slice.perBand.get(band);
- int total = m.values().stream().mapToInt(Integer::intValue).sum();
- if (total == 0) return 0;
- int match = 0;
- for (ResourceKey k : expected) match += m.getOrDefault(k, 0);
- return 100.0 * match / total;
- }
-
- /** Ratio of one or more biomes across a whole slice. */
- private static double biomeRatio(Slice slice, ResourceKey... keys) {
- int total = slice.global.values().stream().mapToInt(Integer::intValue).sum();
- if (total == 0) return 0;
- int match = 0;
- for (ResourceKey k : keys) match += slice.global.getOrDefault(k, 0);
- return 100.0 * match / total;
- }
-
- /** Ratio of a biome within a single band of a slice. */
- private static double biomeRatioInBand(Slice slice, BiomeBand band, ResourceKey key) {
- Map, Integer> m = slice.perBand.get(band);
- int total = m.values().stream().mapToInt(Integer::intValue).sum();
- if (total == 0) return 0;
- return 100.0 * m.getOrDefault(key, 0) / total;
- }
-
- /** Resolve all biome keys that belong to a tag, via the real registry. */
- private static Set> resolveTagKeys(HolderGetter getter, net.minecraft.tags.TagKey tag) {
- Set> keys = new HashSet<>();
- getter.get(tag).ifPresent(set -> set.forEach(h -> h.unwrapKey().ifPresent(keys::add)));
- return keys;
- }
-
- private static boolean isSafeSpawn(ResourceKey key) {
- return Set.of(Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST,
- Biomes.FLOWER_FOREST, Biomes.MEADOW, Biomes.CHERRY_GROVE).contains(key);
- }
-
- /** A sampled depth slice: global counts + per-band counts. */
- private record Slice(Map, Integer> global,
- Map, Integer>> perBand) {
- }
-
- // Local assert helpers (no JUnit in the main classpath at runtime).
- private static void assertTrue(boolean condition, String msg) {
- if (!condition) throw new AssertionError(msg);
- }
-
- private static void assertNotNull(Object o, String msg) {
- if (o == null) throw new AssertionError(msg);
- }
-
- private static void assertEquals(Object expected, Object actual, String msg) {
- if (!java.util.Objects.equals(expected, actual)) {
- throw new AssertionError(msg + " (expected=" + expected + ", actual=" + actual + ")");
- }
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMapCommand.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMapCommand.java
deleted file mode 100644
index f858a33f..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMapCommand.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import com.mojang.brigadier.CommandDispatcher;
-import com.mojang.brigadier.arguments.IntegerArgumentType;
-import com.mojang.brigadier.context.CommandContext;
-import net.mcreator.customoregen.CustomOreGenMod;
-import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.commands.Commands;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderGetter;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.biome.Biomes;
-import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.common.EventBusSubscriber;
-import net.neoforged.neoforge.event.RegisterCommandsEvent;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * {@code /latitude map [radius] [step]} — renders a top-down biome map of the latitude world.
- *
- * Samples {@link LatitudeBiomeSource} on a large square grid (independent of the current
- * world's biome source, so it works in any world) and writes:
- *
- * - {@code run/latitude/latitude_map.png} — one colour per biome category (the "map view"),
- * - {@code run/latitude/latitude_report.txt} — per-band distribution + validation invariants.
- *
- *
- * Use this to validate the climate distribution without exploring by hand.
- */
-@EventBusSubscriber(modid = CustomOreGenMod.MODID, bus = EventBusSubscriber.Bus.GAME)
-public class LatitudeMapCommand {
-
- private static final int DEFAULT_RADIUS = 24000;
- private static final int DEFAULT_STEP = 60;
-
- // Biome key -> colour category (kept in sync with BiomeBand pools)
- private static final Map, Integer> COLORS = new HashMap<>();
-
- static {
- col(0xB6E388, Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST,
- Biomes.FLOWER_FOREST, Biomes.MEADOW, Biomes.CHERRY_GROVE); // safe spawn / temperate
- col(0xC8E6FF, Biomes.SNOWY_PLAINS, Biomes.ICE_SPIKES, Biomes.SNOWY_TAIGA, Biomes.GROVE,
- Biomes.SNOWY_SLOPES, Biomes.JAGGED_PEAKS, Biomes.FROZEN_PEAKS); // frozen
- col(0x8FB8D6, Biomes.TAIGA, Biomes.OLD_GROWTH_PINE_TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA,
- Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST, Biomes.WINDSWEPT_GRAVELLY_HILLS); // cold
- col(0x7CC576, Biomes.DARK_FOREST, Biomes.OLD_GROWTH_BIRCH_FOREST); // temperate
- col(0xE0C068, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.WINDSWEPT_SAVANNA); // warm
- col(0xE0884C, Biomes.DESERT, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS,
- Biomes.JUNGLE, Biomes.SPARSE_JUNGLE, Biomes.BAMBOO_JUNGLE); // hot
- col(0x2B5C8A, Biomes.OCEAN, Biomes.DEEP_OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN,
- Biomes.WARM_OCEAN, Biomes.FROZEN_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.COLD_OCEAN,
- Biomes.DEEP_COLD_OCEAN, Biomes.RIVER, Biomes.FROZEN_RIVER); // water
- col(0x5B7A3A, Biomes.SWAMP); // swamp (should be rare pockets)
- col(0x3A5A3A, Biomes.MANGROVE_SWAMP); // mangrove
- col(0x6B4E3A, Biomes.LUSH_CAVES, Biomes.DRIPSTONE_CAVES, Biomes.DEEP_DARK); // underground
- }
-
- private static void col(int rgb, ResourceKey... keys) {
- for (ResourceKey k : keys) COLORS.put(k, rgb);
- }
-
- @SubscribeEvent
- public static void onRegisterCommands(RegisterCommandsEvent event) {
- CommandDispatcher dispatcher = event.getDispatcher();
- dispatcher.register(Commands.literal("latitude")
- .requires(source -> source.hasPermission(2))
- .then(Commands.literal("map")
- .executes(ctx -> run(ctx, DEFAULT_RADIUS, DEFAULT_STEP))
- .then(Commands.argument("radius", IntegerArgumentType.integer(1000, 100000))
- .executes(ctx -> run(ctx, IntegerArgumentType.getInteger(ctx, "radius"), DEFAULT_STEP))
- .then(Commands.argument("step", IntegerArgumentType.integer(4, 1000))
- .executes(ctx -> run(ctx,
- IntegerArgumentType.getInteger(ctx, "radius"),
- IntegerArgumentType.getInteger(ctx, "step")))))));
- }
-
- private static int run(CommandContext ctx, int radius, int step) {
- CommandSourceStack src = ctx.getSource();
- if (!(src.getLevel() instanceof ServerLevel serverLevel)) {
- src.sendFailure(Component.literal("Must be run on a server level."));
- return 0;
- }
-
- long seed = serverLevel.getSeed();
- HolderGetter getter = serverLevel.registryAccess().lookupOrThrow(Registries.BIOME);
- LatitudeBiomeSource source = new LatitudeBiomeSource(seed, getter);
-
- int dim = (2 * radius) / step + 1;
- src.sendSystemMessage(Component.literal(
- "\u00A7b[Latitude]\u00A7r Sampling " + dim + "x" + dim + " grid (radius=" + radius + ", step=" + step + ")..."));
-
- BufferedImage img = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_RGB);
- Map, Integer> global = new HashMap<>();
- Map, Integer>> perBand = new EnumMap<>(BiomeBand.class);
- for (BiomeBand b : BiomeBand.values()) perBand.put(b, new HashMap<>());
-
- for (int zi = 0; zi < dim; zi++) {
- for (int xi = 0; xi < dim; xi++) {
- int blockX = -radius + xi * step;
- int blockZ = -radius + zi * step;
- Holder holder = source.getNoiseBiome(blockX >> 2, 64 >> 2, blockZ >> 2, null);
- ResourceKey key = holder.unwrapKey().orElse(null);
-
- global.merge(key, 1, Integer::sum);
- perBand.get(BiomeBand.fromTemperature(blockZ / 16000.0)).merge(key, 1, Integer::sum);
-
- int rgb = key == null ? 0x888888 : COLORS.getOrDefault(key, 0x888888);
- img.setRGB(xi, dim - 1 - zi, rgb); // flip Z so north is at the top
- }
- }
-
- // ---- Spawn biome ----
- ResourceKey spawnKey = source.getNoiseBiome(0, 64 >> 2, 0, null).unwrapKey().orElse(null);
-
- // ---- Write PNG ----
- try {
- Files.createDirectories(Path.of("latitude"));
- ImageIO.write(img, "png", Path.of("latitude", "latitude_map.png").toFile());
- } catch (Exception e) {
- CustomOreGenMod.LOGGER.error("Latitude map: failed to write PNG", e);
- src.sendFailure(Component.literal("Failed to write PNG: " + e.getMessage()));
- return 0;
- }
-
- // ---- Build report ----
- StringBuilder r = new StringBuilder();
- r.append("Latitude World Map Report\n");
- r.append("seed=").append(seed).append(" radius=").append(radius).append(" step=").append(step)
- .append(" grid=").append(dim).append("x").append(dim).append("\n\n");
- r.append("Spawn biome @ (0,0): ").append(spawnKey).append("\n\n");
-
- int total = global.values().stream().mapToInt(Integer::intValue).sum();
- r.append("Global biome distribution (top 15):\n");
- global.entrySet().stream()
- .sorted(Map.Entry., Integer>comparingByValue().reversed())
- .limit(15)
- .forEach(e -> r.append(String.format(" %-45s %6.2f%%%n", e.getKey(), 100.0 * e.getValue() / total)));
-
- List warnings = new ArrayList<>();
- for (BiomeBand band : BiomeBand.values()) {
- Map, Integer> m = perBand.get(band);
- int bt = m.values().stream().mapToInt(Integer::intValue).sum();
- if (bt == 0) continue;
- int swamp = m.getOrDefault(Biomes.SWAMP, 0) + m.getOrDefault(Biomes.MANGROVE_SWAMP, 0);
- double swampPct = 100.0 * swamp / bt;
- r.append("\nBand ").append(band).append(" (").append(bt).append(" samples, swamp+mangrove ")
- .append(String.format("%.2f%%", swampPct)).append("):\n");
- m.entrySet().stream()
- .sorted(Map.Entry., Integer>comparingByValue().reversed())
- .limit(6)
- .forEach(e -> r.append(String.format(" %-43s %6.2f%%%n", e.getKey(), 100.0 * e.getValue() / bt)));
- if (swampPct > 15.0) {
- warnings.add(band + " has " + String.format("%.1f%%", swampPct) + " swamp (expected <15%)");
- }
- }
-
- // Invariant checks
- r.append("\n=== Validation ===\n");
- boolean spawnOk = spawnKey != null && isSafeSpawn(spawnKey);
- r.append("Spawn on safe biome: ").append(spawnOk ? "PASS" : "FAIL (" + spawnKey + ")").append("\n");
- double frozenCold = bandRatio(perBand.get(BiomeBand.FROZEN), Set.of(
- Biomes.SNOWY_PLAINS, Biomes.ICE_SPIKES, Biomes.SNOWY_TAIGA, Biomes.GROVE, Biomes.SNOWY_SLOPES,
- Biomes.JAGGED_PEAKS, Biomes.FROZEN_PEAKS, Biomes.TAIGA, Biomes.OLD_GROWTH_PINE_TAIGA,
- Biomes.OLD_GROWTH_SPRUCE_TAIGA, Biomes.WINDSWEPT_HILLS, Biomes.WINDSWEPT_FOREST,
- Biomes.FROZEN_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.COLD_OCEAN, Biomes.DEEP_COLD_OCEAN,
- Biomes.FROZEN_RIVER));
- r.append(String.format("North (FROZEN) cold/frozen ratio: %.1f%% (want >60%%)%n", frozenCold));
- double hotRatio = bandRatio(perBand.get(BiomeBand.HOT), Set.of(
- Biomes.DESERT, Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS,
- Biomes.JUNGLE, Biomes.SPARSE_JUNGLE, Biomes.BAMBOO_JUNGLE, Biomes.SAVANNA,
- Biomes.SAVANNA_PLATEAU, Biomes.WARM_OCEAN));
- r.append(String.format("South (HOT) warm/hot ratio: %.1f%% (want >60%%)%n", hotRatio));
- r.append("Warnings: ").append(warnings.isEmpty() ? "none" : warnings).append("\n");
-
- try {
- Files.writeString(Path.of("latitude", "latitude_report.txt"), r.toString());
- } catch (Exception e) {
- CustomOreGenMod.LOGGER.error("Latitude map: failed to write report", e);
- }
-
- // ---- Summary to chat ----
- src.sendSystemMessage(Component.literal("\u00A7a[Latitude]\u00A7r Map + report saved to /latitude/"));
- src.sendSystemMessage(Component.literal(" Spawn: " + spawnKey + (spawnOk ? " \u00A7aOK\u00A7r" : " \u00A7cBAD\u00A7r")));
- src.sendSystemMessage(Component.literal(String.format(
- " North cold/frozen: %.0f%% | South hot: %.0f%% | Swamp warnings: %d",
- frozenCold, hotRatio, warnings.size())));
- return 1;
- }
-
- private static double bandRatio(Map, Integer> m, Set> expected) {
- int total = m.values().stream().mapToInt(Integer::intValue).sum();
- if (total == 0) return 0;
- int match = 0;
- for (ResourceKey k : expected) match += m.getOrDefault(k, 0);
- return 100.0 * match / total;
- }
-
- private static boolean isSafeSpawn(ResourceKey key) {
- Set> safe = new HashSet<>(List.of(
- Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST, Biomes.BIRCH_FOREST,
- Biomes.FLOWER_FOREST, Biomes.MEADOW, Biomes.CHERRY_GROVE));
- return safe.contains(key);
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMath.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMath.java
deleted file mode 100644
index 844a782c..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeMath.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-/**
- * Pure (registry-free) geometry helpers for the latitude world type.
- *
- * These methods exist so that the core invariants of {@link LatitudeBiomeSource}
- * can be unit-tested without a loaded biome registry: temperature derivation, the
- * 3-zone underground model, the spawn safe zone, and the dual-octave biome index
- * math. {@link LatitudeBiomeSource} delegates to these helpers, so the two stay
- * in lock-step by construction (no behaviour drift).
- */
-public final class LatitudeMath {
-
- private LatitudeMath() {}
-
- // ------------------------------------------------------------------
- // Surface / climate tunables (must mirror LatitudeBiomeSource)
- // ------------------------------------------------------------------
-
- public static final double TEMPERATURE_SCALE = 16000.0;
- public static final double BOUNDARY_NOISE_SCALE = 0.00015;
- public static final double BOUNDARY_NOISE_AMPLITUDE = 0.15;
- public static final double SURFACE_SELECTOR_SCALE = 0.00033;
- public static final double OCEAN_NOISE_SCALE = 0.0011;
- public static final double OCEAN_THRESHOLD = 0.30;
- public static final double MOISTURE_SCALE = 0.0009;
- public static final double MOISTURE_THRESHOLD = 0.55;
-
- // ------------------------------------------------------------------
- // Underground tunables (3-zone model)
- // ------------------------------------------------------------------
-
- public static final int DEEP_ZONE_TOP = -30;
- public static final int MID_CAVE_TOP = 0;
- public static final double CAVE_SCALE = 0.003;
- public static final double CAVE_THRESHOLD = 0.38;
- public static final double DEEP_DARK_SCALE = 0.0011;
- public static final double DEEP_DARK_SCALE_Y = 0.012;
- public static final double DEEP_DARK_THRESHOLD = 0.55;
-
- // ------------------------------------------------------------------
- // Spawn safe zone
- // ------------------------------------------------------------------
-
- public static final int SPAWN_SAFE_RADIUS = 540;
- public static final double SPAWN_SELECTOR_SCALE = 0.004;
-
- /** Underground vertical zone, mirroring {@link LatitudeBiomeSource#applyCaveOverrides}. */
- public enum Zone {
- /** {@code Y < DEEP_ZONE_TOP} — deep zone, legendary Deep Dark pockets. */
- DEEP,
- /** {@code DEEP_ZONE_TOP <= Y < MID_CAVE_TOP} — mid caves, lush/dripstone pockets. */
- MID_CAVE,
- /** {@code Y >= MID_CAVE_TOP} — no cave override; latitude biome as-is. */
- SURFACE
- }
-
- /** Band the column falls into based on its Y coordinate. Pure function. */
- public static Zone zoneForY(int blockY) {
- if (blockY < DEEP_ZONE_TOP) return Zone.DEEP;
- if (blockY < MID_CAVE_TOP) return Zone.MID_CAVE;
- return Zone.SURFACE;
- }
-
- /**
- * Raw latitude temperature contribution from the Z coordinate, before the boundary
- * wobble is applied. {@code blockZ / TEMPERATURE_SCALE} clamped to {@code [-1, 1]}.
- * Pure function.
- */
- public static double rawLatitudeTemperature(int blockZ) {
- return clamp(blockZ / TEMPERATURE_SCALE, -1.0, 1.0);
- }
-
- /**
- * Combine the raw latitude temperature with a precomputed boundary wobble (the output of
- * {@code boundaryNoise.noise(...) * BOUNDARY_NOISE_AMPLITUDE}), then clamp to the valid
- * temperature range. Pure function.
- */
- public static double temperature(int blockZ, double boundaryWobble) {
- return clamp(blockZ / TEMPERATURE_SCALE + boundaryWobble, -1.0, 1.0);
- }
-
- /** True if the (blockX, blockZ) column is inside the guaranteed safe spawn square. Pure. */
- public static boolean isInSpawnSafeZone(int blockX, int blockZ) {
- return Math.abs(blockX) < SPAWN_SAFE_RADIUS && Math.abs(blockZ) < SPAWN_SAFE_RADIUS;
- }
-
- /**
- * Normalised selector value in {@code [0, 1]} from two noise samples, mirroring the
- * dual-octave flattening used by {@link LatitudeBiomeSource#pickBiome}.
- *
- * @param n1 first octave noise value (any range ImprovedNoise produces)
- * @param n2 second octave noise value (at a different offset)
- * @return a value in {@code [0, 1]}
- */
- public static double normalisedSelector(double n1, double n2) {
- double combined = (n1 + n2 * 0.5) / 1.5;
- return clamp(combined * 0.5 + 0.5, 0.0, 1.0);
- }
-
- /**
- * Map a normalised selector value in {@code [0, 1]} to a list index, clamped so it can
- * never leave {@code [0, size-1]}. Mirrors the index math in {@code pickBiome}.
- * Pure. {@code size} must be {@code >= 1}.
- */
- public static int selectorIndex(double normalised, int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("size must be >= 1, was " + size);
- }
- int idx = (int) (normalised * size);
- if (idx >= size) idx = size - 1;
- if (idx < 0) idx = 0;
- return idx;
- }
-
- /**
- * Is the deep-Dark override active for this column, given the precomputed deep-dark noise
- * value (output of {@code deepDarkNoise.noise(...)})? Only meaningful in the DEEP zone;
- * callers should gate on {@link #zoneForY} first. Pure.
- */
- public static boolean isDeepDarkPocket(double deepDarkNoise) {
- return deepDarkNoise > DEEP_DARK_THRESHOLD;
- }
-
- /** Is the mid-cave lush/dripstone pocket override active for this column? Pure. */
- public static boolean isMidCavePocket(double caveNoise) {
- return caveNoise > CAVE_THRESHOLD;
- }
-
- private static double clamp(double value, double min, double max) {
- return value < min ? min : (value > max ? max : value);
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSignalDensityFunction.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSignalDensityFunction.java
new file mode 100644
index 00000000..6306d201
--- /dev/null
+++ b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSignalDensityFunction.java
@@ -0,0 +1,62 @@
+package net.mcreator.customoregen.worldgen;
+
+import com.mojang.serialization.MapCodec;
+import net.minecraft.util.KeyDispatchDataCodec;
+import net.minecraft.world.level.levelgen.DensityFunction;
+
+/**
+ * A custom {@link DensityFunction} that exposes the world's latitude as a Z-only signal,
+ * something the vanilla density-function vocabulary cannot do (only {@code y} is reachable, via
+ * {@code y_clamped_gradient}).
+ *
+ * The value is {@code clamp(blockZ / TEMPERATURE_SCALE, -1, 1)}. {@code -1} = far north
+ * (cold), {@code 0} = equator (temperate), {@code +1} = far south (hot). It feeds the
+ * {@code custom_ore_gen:latitude_temperature} density function, which replaces the vanilla
+ * temperature in the Lithosphere noise settings so that biome selection follows latitude.
+ *
+ * Registered as density-function type {@code custom_ore_gen:latitude_signal}; reference it from a
+ * density-function JSON as {@code { "type": "custom_ore_gen:latitude_signal" }}.
+ */
+public record LatitudeSignalDensityFunction() implements DensityFunction.SimpleFunction {
+
+ /**
+ * Number of blocks for the temperature to go from 0 (equator) to ±1 (pole).
+ *
+ * Tuned to match the ore-zone thresholds (default ±8000): at Z=8000 the latitude is
+ * 0.5, which is the vanilla boundary between temperate and warm climates, so hot ores
+ * (copper/gold/redstone) line up with hot-looking biomes. Lush caves (temperature ~0.7)
+ * therefore appear around Z=11000, just inside the hot ore zone.
+ */
+ private static final double TEMPERATURE_SCALE = 16000.0;
+
+ /** MapCodec (no fields): a single canonical instance, round-trips as a bare type tag. */
+ public static final MapCodec DATA_CODEC =
+ MapCodec.unit(new LatitudeSignalDensityFunction());
+
+ /** {@link DensityFunction#codec()} wrapper the framework expects. */
+ public static final KeyDispatchDataCodec CODEC =
+ KeyDispatchDataCodec.of(DATA_CODEC);
+
+ @Override
+ public double compute(DensityFunction.FunctionContext context) {
+ double latitude = context.blockZ() / TEMPERATURE_SCALE;
+ if (latitude < -1.0) return -1.0;
+ if (latitude > 1.0) return 1.0;
+ return latitude;
+ }
+
+ @Override
+ public double minValue() {
+ return -1.0;
+ }
+
+ @Override
+ public double maxValue() {
+ return 1.0;
+ }
+
+ @Override
+ public KeyDispatchDataCodec extends DensityFunction> codec() {
+ return CODEC;
+ }
+}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSpawnHandler.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSpawnHandler.java
deleted file mode 100644
index 938a04d6..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeSpawnHandler.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import net.mcreator.customoregen.CustomOreGenMod;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Holder;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.tags.TagKey;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.biome.Biomes;
-import net.minecraft.world.level.levelgen.Heightmap;
-import net.minecraft.world.level.storage.ServerLevelData;
-import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.common.EventBusSubscriber;
-import net.neoforged.neoforge.event.level.LevelEvent;
-
-import java.util.Set;
-
-/**
- * Forces the world spawn point to a plains-like biome near the origin.
- *
- * Because {@link LatitudeBiomeSource} places temperate biomes around Z=0, a plains
- * or forest biome is always available close to spawn. This handler runs once per server
- * lifetime when the overworld loads, scans a growing square around the origin and pins
- * the default spawn point to the first matching biome. The player therefore always
- * starts the game on open, buildable terrain instead of a swamp, mountain or ocean.
- */
-@EventBusSubscriber(modid = CustomOreGenMod.MODID)
-public class LatitudeSpawnHandler {
-
- /** Biomes considered a good starting point (open, buildable temperate terrain). */
- private static final Set> SPAWN_BIOMES = Set.of(
- Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS,
- Biomes.FOREST, Biomes.BIRCH_FOREST, Biomes.FLOWER_FOREST,
- Biomes.MEADOW, Biomes.CHERRY_GROVE
- );
-
- /** Maximum search radius (in blocks) around the origin. Kept inside the BiomeSource */
- /** SPAWN_SAFE_RADIUS (540) so the safe-square guarantee applies to everything we find. */
- private static final int MAX_RADIUS = 512;
-
- /** Step between sampled positions. */
- private static final int STEP = 8;
-
- /** Surface Y used for biome probing - must match LatitudeGameTest.SURFACE_Y semantics. */
- private static final int SURFACE_Y = 64;
-
- private static volatile boolean initialized = false;
-
- @SubscribeEvent
- public static void onLevelLoad(LevelEvent.Load event) {
- if (initialized) {
- return;
- }
- if (!(event.getLevel() instanceof ServerLevel level)) {
- return;
- }
- if (level.dimension() != Level.OVERWORLD) {
- return;
- }
-
- initialized = true;
-
- if (!(level.getLevelData() instanceof ServerLevelData levelData)) {
- return;
- }
-
- // Probe biomes at the SURFACE (y=64), not at y=0. Underground the latitude biome extends
- // downwards by design, so probing at y=0 could match a SPAWN_BIOMES that differs from what
- // the player actually sees on the surface. The BiomeSource spawn-safe square covers the
- // first 540 blocks around the origin, so probing at surface y and within that square reliably
- // lands on plains/forest - never dark_forest (which is only in the temperate surface pool,
- // used outside the safe square).
- BlockPos current = levelData.getSpawnPos();
- if (isSpawnBiomeAtSurface(level, current.getX(), current.getZ())) {
- return; // Already on a good biome, leave it alone.
- }
-
- BlockPos found = findSpawnBiome(level);
- if (found == null) {
- CustomOreGenMod.LOGGER.warn("Latitude: no suitable spawn biome found within {} blocks, keeping {}", MAX_RADIUS, current);
- return;
- }
-
- int y = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, found.getX(), found.getZ());
- BlockPos spawn = new BlockPos(found.getX(), y, found.getZ());
- level.setDefaultSpawnPos(spawn, 0.0f);
- CustomOreGenMod.LOGGER.info("Latitude: spawn point set to {} ({})", spawn,
- level.getBiome(spawn).unwrapKey().map(Object::toString).orElse("?"));
- }
-
- private static boolean isSpawnBiomeAtSurface(ServerLevel level, int x, int z) {
- Holder biome = level.getBiome(new BlockPos(x, SURFACE_Y, z));
- return biome.unwrapKey().map(SPAWN_BIOMES::contains).orElse(false);
- }
-
- private static BlockPos findSpawnBiome(ServerLevel level) {
- // Concentric square rings starting from the origin. We probe at SURFACE_Y because the
- // latitude biome at y=0 can legitimately differ from the surface biome.
- for (int radius = 0; radius <= MAX_RADIUS; radius += STEP) {
- for (int x = -radius; x <= radius; x += STEP) {
- for (int z = -radius; z <= radius; z += STEP) {
- // Only scan the outer ring of each pass to avoid re-checking inner cells.
- if (Math.abs(x) != radius && Math.abs(z) != radius && radius != 0) {
- continue;
- }
- if (isSpawnBiomeAtSurface(level, x, z)) {
- return new BlockPos(x, 0, z);
- }
- }
- }
- }
- return null;
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/LatitudeZonePlacement.java b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeZonePlacement.java
new file mode 100644
index 00000000..05ce8720
--- /dev/null
+++ b/src/main/java/net/mcreator/customoregen/worldgen/LatitudeZonePlacement.java
@@ -0,0 +1,77 @@
+package net.mcreator.customoregen.worldgen;
+
+import com.mojang.serialization.MapCodec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+import net.minecraft.core.BlockPos;
+import net.minecraft.util.RandomSource;
+import net.minecraft.world.level.levelgen.placement.PlacementContext;
+import net.minecraft.world.level.levelgen.placement.PlacementFilter;
+import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
+
+/**
+ * Placement modifier that filters ore placement by Z coordinate (latitude zone).
+ *
+ * When the player's Z position is in the configured zone, the ore is placed; otherwise it is
+ * skipped. This replaces the biome-tag-based approach and works universally with any biome mod
+ * (BOP, Terralith, etc.) without needing to classify every biome manually.
+ *
+ * Three zones exist:
+ *
+ * - {@code COLD}: Z < {@code coldThreshold} (negative Z, north)
+ * - {@code HOT}: Z > {@code hotThreshold} (positive Z, south)
+ * - {@code TEMPERATE}: between the two thresholds
+ *
+ *
+ * Registered as placement-modifier type {@code custom_ore_gen:latitude_zone}.
+ */
+public class LatitudeZonePlacement extends PlacementFilter {
+
+ public enum Zone {
+ COLD("cold"),
+ HOT("hot"),
+ TEMPERATE("temperate");
+
+ private final String serializedName;
+ Zone(String name) { this.serializedName = name; }
+ public String getSerializedName() { return serializedName; }
+
+ public static Zone byName(String name) {
+ for (Zone z : values()) {
+ if (z.serializedName.equals(name)) return z;
+ }
+ return TEMPERATE;
+ }
+ }
+
+ public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(
+ instance -> instance.group(
+ com.mojang.serialization.Codec.STRING.fieldOf("zone")
+ .xmap(Zone::byName, Zone::getSerializedName)
+ .forGetter(p -> p.zone)
+ ).apply(instance, instance.stable(LatitudeZonePlacement::new))
+ );
+
+ private final Zone zone;
+
+ public LatitudeZonePlacement(Zone zone) {
+ this.zone = zone;
+ }
+
+ @Override
+ protected boolean shouldPlace(PlacementContext context, RandomSource random, BlockPos pos) {
+ int z = pos.getZ();
+ int coldZ = LatitudeConfig.getColdZoneZ();
+ int hotZ = LatitudeConfig.getHotZoneZ();
+
+ return switch (zone) {
+ case COLD -> z < coldZ;
+ case HOT -> z > hotZ;
+ case TEMPERATE -> z >= coldZ && z <= hotZ;
+ };
+ }
+
+ @Override
+ public PlacementModifierType> type() {
+ return WorldGenRegistration.LATITUDE_ZONE_PLACEMENT.value();
+ }
+}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/OreAuditHandler.java b/src/main/java/net/mcreator/customoregen/worldgen/OreAuditHandler.java
deleted file mode 100644
index 1661a53a..00000000
--- a/src/main/java/net/mcreator/customoregen/worldgen/OreAuditHandler.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Holder;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.block.Block;
-import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.common.EventBusSubscriber;
-import net.neoforged.neoforge.event.server.ServerStartedEvent;
-
-import net.mcreator.customoregen.CustomOreGenMod;
-import net.mcreator.customoregen.init.CustomOreGenModBlocks;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Temporary diagnostic: only active when a {@code .oreaudit} marker file exists in the
- * server working directory (create it to run the audit, delete it afterwards). On server
- * start it forces real chunk generation in a grid around the origin, counts custom ore blocks
- * per surface biome, writes {@code ore_audit_report.txt}, and then stops the server.
- *
- * Warning: this handler calls {@code System.exit(0)} at the end of the audit. It is
- * therefore a developer-only utility that must never be enabled in production. The
- * equivalent, non-destructive proof that ores place in every biome is covered by
- * {@link LatitudeGameTest} (run with {@code ./gradlew runGameTestServer}).
- */
-@EventBusSubscriber
-public class OreAuditHandler {
-
- private static final int CHUNKS_PER_AXIS = 12; // 12x12 chunks = 192x192 blocks
- private static final int Y_MIN = -8;
- private static final int Y_MAX = 32;
-
- @SubscribeEvent
- public static void onServerStarted(ServerStartedEvent event) {
- Path flag = Path.of(".oreaudit");
- if (!java.nio.file.Files.exists(flag)) {
- return;
- }
- MinecraftServer server = event.getServer();
- new Thread(() -> runAudit(server), "ore-audit").start();
- }
-
- private static void runAudit(MinecraftServer server) {
- try {
- Thread.sleep(2000); // let the server settle
- ServerLevel overworld = server.overworld();
-
- // Pre-generate chunks in a grid so features are placed.
- CustomOreGenMod.LOGGER.info("[ore-audit] Generating {}x{} chunks...", CHUNKS_PER_AXIS, CHUNKS_PER_AXIS);
- for (int cx = 0; cx < CHUNKS_PER_AXIS; cx++) {
- for (int cz = 0; cz < CHUNKS_PER_AXIS; cz++) {
- overworld.getChunk(cx, cz);
- }
- }
- CustomOreGenMod.LOGGER.info("[ore-audit] Chunks generated, scanning ores...");
-
- // Map: biome -> ore block -> count
- Map> byBiome = new LinkedHashMap<>();
- int[] shardTotal = {0};
- int[] ironTotal = {0};
- int[] coalTotal = {0};
-
- Block shardSurface = CustomOreGenModBlocks.SHARDDIAMONDBLOCKORE.get();
- Block shardDeep = CustomOreGenModBlocks.DEEPSLATESHARDDIAMONDORE.get();
- Block ironSurface = CustomOreGenModBlocks.IRONORE.get();
- Block ironDeep = CustomOreGenModBlocks.DEEPSLATEIRONORE.get();
- Block coal = CustomOreGenModBlocks.CONCENTRATEDCOALORE.get();
-
- for (int cx = 0; cx < CHUNKS_PER_AXIS; cx++) {
- for (int cz = 0; cz < CHUNKS_PER_AXIS; cz++) {
- int baseX = cx << 4;
- int baseZ = cz << 4;
- for (int x = 0; x < 16; x++) {
- for (int z = 0; z < 16; z++) {
- Holder biomeHolder = overworld.getBiome(new BlockPos(baseX + x, 64, baseZ + z));
- String biomeKey = biomeHolder.unwrapKey()
- .map(k -> k.location().toString()).orElse("unknown");
- Map ores = byBiome.computeIfAbsent(biomeKey, k -> new LinkedHashMap<>());
- for (int y = Y_MIN; y <= Y_MAX; y++) {
- Block b = overworld.getBlockState(new BlockPos(baseX + x, y, baseZ + z)).getBlock();
- String name = null;
- if (b == shardSurface) { name = "shard_diamond"; shardTotal[0]++; }
- else if (b == shardDeep) { name = "deepslate_shard_diamond"; shardTotal[0]++; }
- else if (b == ironSurface) { name = "iron"; ironTotal[0]++; }
- else if (b == ironDeep) { name = "deepslate_iron"; ironTotal[0]++; }
- else if (b == coal) { name = "concentrated_coal"; coalTotal[0]++; }
- if (name != null) ores.merge(name, 1, Integer::sum);
- }
- }
- }
- }
- }
-
- StringBuilder r = new StringBuilder();
- r.append("=== ORE AUDIT (real chunk generation) ===\n");
- r.append(String.format("Scanned %dx%d chunks, Y=%d..%d%n", CHUNKS_PER_AXIS, CHUNKS_PER_AXIS, Y_MIN, Y_MAX));
- r.append(String.format("Totals: shard=%d iron=%d coal=%d%n%n", shardTotal[0], ironTotal[0], coalTotal[0]));
- r.append("Per biome (only biomes with >=1 ore shown):\n");
- for (var e : byBiome.entrySet()) {
- if (e.getValue().isEmpty()) continue;
- r.append(String.format(" %-40s %s%n", e.getKey(), e.getValue()));
- }
- r.append("\nBiomes with ZERO ores (sampled):\n");
- int zeroCount = 0;
- for (var e : byBiome.entrySet()) {
- if (e.getValue().isEmpty()) {
- r.append(" ").append(e.getKey()).append("\n");
- zeroCount++;
- }
- }
- if (zeroCount == 0) r.append(" (none - every sampled biome has ores)\n");
-
- Path out = Path.of("ore_audit_report.txt");
- Files.writeString(out, r.toString());
- CustomOreGenMod.LOGGER.info("[ore-audit] Report written to {}", out.toAbsolutePath());
- CustomOreGenMod.LOGGER.info("[ore-audit] Totals: shard={} iron={} coal={}", shardTotal[0], ironTotal[0], coalTotal[0]);
- CustomOreGenMod.LOGGER.info("[ore-audit] Biomes with ores: {}, biomes with zero: {}",
- byBiome.values().stream().filter(m -> !m.isEmpty()).count(), zeroCount);
- } catch (Throwable t) {
- CustomOreGenMod.LOGGER.error("[ore-audit] failed", t);
- } finally {
- try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
- System.exit(0);
- }
- }
-}
diff --git a/src/main/java/net/mcreator/customoregen/worldgen/WorldGenRegistration.java b/src/main/java/net/mcreator/customoregen/worldgen/WorldGenRegistration.java
index 7490c689..1061b5b4 100644
--- a/src/main/java/net/mcreator/customoregen/worldgen/WorldGenRegistration.java
+++ b/src/main/java/net/mcreator/customoregen/worldgen/WorldGenRegistration.java
@@ -2,7 +2,8 @@ package net.mcreator.customoregen.worldgen;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.registries.Registries;
-import net.minecraft.world.level.biome.BiomeSource;
+import net.minecraft.world.level.levelgen.DensityFunction;
+import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import net.neoforged.neoforge.common.world.BiomeModifier;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
@@ -10,23 +11,24 @@ import net.neoforged.neoforge.registries.NeoForgeRegistries;
/**
* Registration of custom worldgen codecs used by the mod.
- *
- *
- * - {@code latitude} — the custom latitude {@link BiomeSource} codec
- * referenced from world presets.
- * - {@code config_gated_features} — a {@link BiomeModifier} type that
- * only adds ore features when their config toggle is enabled.
- *
*/
public class WorldGenRegistration {
- public static final DeferredRegister> BIOME_SOURCES =
- DeferredRegister.create(Registries.BIOME_SOURCE, "custom_ore_gen");
+ /** Custom density-function types. */
+ public static final DeferredRegister> DENSITY_FUNCTION_TYPES =
+ DeferredRegister.create(Registries.DENSITY_FUNCTION_TYPE, "custom_ore_gen");
- public static final DeferredHolder, MapCodec extends BiomeSource>> LATITUDE =
- BIOME_SOURCES.register("latitude", () -> LatitudeBiomeSource.CODEC);
+ public static final DeferredHolder, MapCodec extends DensityFunction>> LATITUDE_SIGNAL =
+ DENSITY_FUNCTION_TYPES.register("latitude_signal", () -> LatitudeSignalDensityFunction.DATA_CODEC);
- /** Serializer registry for config-gated biome modifiers (see {@link ConfigGatedFeaturesModifier}). */
+ /** Custom placement-modifier types (Z-coordinate-based ore filtering). */
+ public static final DeferredRegister> PLACEMENT_MODIFIERS =
+ DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, "custom_ore_gen");
+
+ public static final DeferredHolder, PlacementModifierType> LATITUDE_ZONE_PLACEMENT =
+ PLACEMENT_MODIFIERS.register("latitude_zone", () -> () -> LatitudeZonePlacement.CODEC);
+
+ /** Serializer registry for config-gated biome modifiers. */
public static final DeferredRegister> BIOME_MODIFIER_SERIALIZERS =
DeferredRegister.create(NeoForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, "custom_ore_gen");
diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml
index 522967d1..d419a3dd 100644
--- a/src/main/resources/META-INF/neoforge.mods.toml
+++ b/src/main/resources/META-INF/neoforge.mods.toml
@@ -23,6 +23,14 @@ description='''${mod_description}'''
# Start of user code block dependencies configuration
+
+[[dependencies."${mod_id}"]]
+ modId="mr_lithosphere"
+ mandatory=true
+ versionRange="[1.7,)"
+ ordering="AFTER"
+ side="BOTH"
+
# Note: optional mods (biomesoplenty, create, mekanism) are intentionally NOT declared
# here. Optional integration is handled via data tags with "required": false entries
# (see data/custom_ore_gen/tags/worldgen/biome/latitude_*_surface.json) and via
@@ -30,3 +38,7 @@ description='''${mod_description}'''
# absent. Declaring them here with mandatory=false + versionRange caused NeoForge to
# fail loading when the mods were not installed (see commit history).
# End of user code block dependencies configuration
+
+# Mixin configuration
+[[mixins]]
+config = "custom_ore_gen.mixins.json"
diff --git a/src/main/resources/custom_ore_gen.mixins.json b/src/main/resources/custom_ore_gen.mixins.json
new file mode 100644
index 00000000..d18cf7d5
--- /dev/null
+++ b/src/main/resources/custom_ore_gen.mixins.json
@@ -0,0 +1,15 @@
+{
+ "required": true,
+ "minVersion": "0.8.5",
+ "package": "net.mcreator.customoregen.mixin",
+ "compatibilityLevel": "JAVA_21",
+ "refmap": "custom_ore_gen.refmap.json",
+ "mixins": [
+ "MultiNoiseBiomeSourceMixin"
+ ],
+ "client": [],
+ "server": [],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_cold_biomes_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_cold_biomes_ores.json
index 4ce08da5..4eccb428 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_cold_biomes_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_cold_biomes_ores.json
@@ -1,20 +1,22 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": "#custom_ore_gen:latitude_cold_surface",
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "vanillaOreVariants",
- "features": [
- "custom_ore_gen:lapisore",
- "custom_ore_gen:deepslatelapisore"
- ]
- },
- {
- "toggle": "concentratedOres",
- "features": [
- "custom_ore_gen:deepslatediamondore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": {
+ "type": "neoforge:any"
+ },
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "vanillaOreVariants",
+ "features": [
+ "custom_ore_gen:lapisore",
+ "custom_ore_gen:deepslatelapisore"
+ ]
+ },
+ {
+ "toggle": "concentratedOres",
+ "features": [
+ "custom_ore_gen:deepslatediamondore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_hot_biomes_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_hot_biomes_ores.json
index acaf9007..211ef031 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_hot_biomes_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_hot_biomes_ores.json
@@ -1,28 +1,30 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": "#custom_ore_gen:latitude_hot_surface",
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "pureGoldenOre",
- "features": [
- "custom_ore_gen:puregoldenore",
- "custom_ore_gen:deepslatepuregoldenore"
- ]
- },
- {
- "toggle": "customCopperOres",
- "features": [
- "custom_ore_gen:copperhighore",
- "custom_ore_gen:copperlowerore"
- ]
- },
- {
- "toggle": "vanillaOreVariants",
- "features": [
- "custom_ore_gen:redstoneore",
- "custom_ore_gen:deepslateredstoneore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": {
+ "type": "neoforge:any"
+ },
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "pureGoldenOre",
+ "features": [
+ "custom_ore_gen:puregoldenore",
+ "custom_ore_gen:deepslatepuregoldenore"
+ ]
+ },
+ {
+ "toggle": "customCopperOres",
+ "features": [
+ "custom_ore_gen:copperhighore",
+ "custom_ore_gen:copperlowerore"
+ ]
+ },
+ {
+ "toggle": "vanillaOreVariants",
+ "features": [
+ "custom_ore_gen:redstoneore",
+ "custom_ore_gen:deepslateredstoneore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_mountain_biomes_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_mountain_biomes_ores.json
index 7180b6da..0b41211c 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_mountain_biomes_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_mountain_biomes_ores.json
@@ -1,13 +1,13 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": "#custom_ore_gen:mountain_biomes",
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "customEmeraldOres",
- "features": [
- "custom_ore_gen:highemeraldore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": "#custom_ore_gen:mountain_biomes",
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "customEmeraldOres",
+ "features": [
+ "custom_ore_gen:highemeraldore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_rare_biomes_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_rare_biomes_ores.json
index 092abef8..7bf08c0e 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_rare_biomes_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_rare_biomes_ores.json
@@ -1,13 +1,13 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": "#custom_ore_gen:rare_biomes",
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "customEmeraldOres",
- "features": [
- "custom_ore_gen:loweremeraldore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": "#custom_ore_gen:rare_biomes",
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "customEmeraldOres",
+ "features": [
+ "custom_ore_gen:loweremeraldore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_shard_diamond_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_shard_diamond_ores.json
index f1cd560d..bc388c31 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_shard_diamond_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_shard_diamond_ores.json
@@ -1,16 +1,16 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": {
- "type": "neoforge:any"
- },
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "shardDiamondOre",
- "features": [
- "custom_ore_gen:sharddiamondblockore",
- "custom_ore_gen:deepslatesharddiamondore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": {
+ "type": "neoforge:any"
+ },
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "shardDiamondOre",
+ "features": [
+ "custom_ore_gen:sharddiamondblockore",
+ "custom_ore_gen:deepslatesharddiamondore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_tempered_biomes_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_tempered_biomes_ores.json
index eba33dd5..d5a7aed0 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_tempered_biomes_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/add_tempered_biomes_ores.json
@@ -1,20 +1,22 @@
{
- "type": "custom_ore_gen:config_gated_features",
- "biomes": "#custom_ore_gen:latitude_temperate_surface",
- "step": "underground_ores",
- "gate_groups": [
- {
- "toggle": "impureOres",
- "features": [
- "custom_ore_gen:ironore",
- "custom_ore_gen:deepslateironore"
- ]
- },
- {
- "toggle": "concentratedOres",
- "features": [
- "custom_ore_gen:concentratedcoalore"
- ]
- }
- ]
-}
+ "type": "custom_ore_gen:config_gated_features",
+ "biomes": {
+ "type": "neoforge:any"
+ },
+ "step": "underground_ores",
+ "gate_groups": [
+ {
+ "toggle": "impureOres",
+ "features": [
+ "custom_ore_gen:ironore",
+ "custom_ore_gen:deepslateironore"
+ ]
+ },
+ {
+ "toggle": "concentratedOres",
+ "features": [
+ "custom_ore_gen:concentratedcoalore"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/remove_vanilla_ores.json b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/z_remove_vanilla_ores.json
similarity index 85%
rename from src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/remove_vanilla_ores.json
rename to src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/z_remove_vanilla_ores.json
index 6c0db785..9e90f4cb 100644
--- a/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/remove_vanilla_ores.json
+++ b/src/main/resources/data/custom_ore_gen/neoforge/biome_modifier/z_remove_vanilla_ores.json
@@ -5,18 +5,21 @@
"minecraft:ore_coal_lower",
"minecraft:ore_coal_upper",
"minecraft:ore_copper_large",
- "minecraft:ore_diamond_large",
- "minecraft:ore_emerald",
- "minecraft:ore_gold",
- "minecraft:ore_iron_small",
- "minecraft:ore_iron_middle",
- "minecraft:ore_lapis_buried",
- "minecraft:ore_lapis",
- "minecraft:ore_redstone",
"minecraft:ore_copper",
"minecraft:ore_diamond",
+ "minecraft:ore_diamond_buried",
+ "minecraft:ore_diamond_large",
+ "minecraft:ore_diamond_medium",
+ "minecraft:ore_emerald",
+ "minecraft:ore_gold",
+ "minecraft:ore_gold_extra",
"minecraft:ore_gold_lower",
+ "minecraft:ore_iron_middle",
+ "minecraft:ore_iron_small",
"minecraft:ore_iron_upper",
+ "minecraft:ore_lapis",
+ "minecraft:ore_lapis_buried",
+ "minecraft:ore_redstone",
"minecraft:ore_redstone_lower"
],
"step": "underground_ores"
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/cold_biomes.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/cold_biomes.json
deleted file mode 100644
index 39da56a9..00000000
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/cold_biomes.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "replace": false,
- "values": [
- "minecraft:taiga",
- "minecraft:frozen_ocean",
- "minecraft:frozen_river",
- "minecraft:snowy_plains",
- "minecraft:snowy_beach",
- "minecraft:snowy_taiga",
- "minecraft:old_growth_pine_taiga",
- "minecraft:grove",
- "minecraft:snowy_slopes",
- "minecraft:jagged_peaks",
- "minecraft:frozen_peaks",
- "minecraft:cold_ocean",
- "minecraft:deep_cold_ocean",
- "minecraft:deep_frozen_ocean",
- "minecraft:ice_spikes",
- {
- "id": "biomesoplenty:auroral_garden",
- "required": false
- },
- {
- "id": "biomesoplenty:cold_desert",
- "required": false
- },
- {
- "id": "biomesoplenty:maple_woods",
- "required": false
- },
- {
- "id": "biomesoplenty:dead_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:tundra",
- "required": false
- },
- {
- "id": "biomesoplenty:bog",
- "required": false
- },
- {
- "id": "biomesoplenty:muskeg",
- "required": false
- },
- {
- "id": "biomesoplenty:old_growth_dead_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:snowblossom_grove",
- "required": false
- },
- {
- "id": "biomesoplenty:snowy_coniferous_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:snowy_fir_clearing",
- "required": false
- },
- {
- "id": "biomesoplenty:snowy_maple_woods",
- "required": false
- }
- ]
-}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/hot_biomes.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/hot_biomes.json
deleted file mode 100644
index 531a7ae4..00000000
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/hot_biomes.json
+++ /dev/null
@@ -1,106 +0,0 @@
-{
- "replace": false,
- "values": [
- "minecraft:desert",
- "minecraft:jungle",
- "minecraft:sparse_jungle",
- "minecraft:savanna",
- "minecraft:savanna_plateau",
- "minecraft:stony_peaks",
- "minecraft:warm_ocean",
- "minecraft:windswept_savanna",
- "minecraft:eroded_badlands",
- "minecraft:bamboo_jungle",
- "minecraft:mangrove_swamp",
- "minecraft:badlands",
- "minecraft:wooded_badlands",
- {
- "id": "biomesoplenty:bayou",
- "required": false
- },
- {
- "id": "biomesoplenty:dryland",
- "required": false
- },
- {
- "id": "biomesoplenty:dune_beach",
- "required": false
- },
- {
- "id": "biomesoplenty:mystic_grove",
- "required": false
- },
- {
- "id": "biomesoplenty:jade_cliffs",
- "required": false
- },
- {
- "id": "biomesoplenty:lavender_field",
- "required": false
- },
- {
- "id": "biomesoplenty:lavender_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:mediterranean_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:orchard",
- "required": false
- },
- {
- "id": "biomesoplenty:pasture",
- "required": false
- },
- {
- "id": "biomesoplenty:prairie",
- "required": false
- },
- {
- "id": "biomesoplenty:lush_desert",
- "required": false
- },
- {
- "id": "biomesoplenty:lush_savanna",
- "required": false
- },
- {
- "id": "biomesoplenty:fungal_jungle",
- "required": false
- },
- {
- "id": "biomesoplenty:floodplain",
- "required": false
- },
- {
- "id": "biomesoplenty:rainforest",
- "required": false
- },
- {
- "id": "biomesoplenty:rocky_rainforest",
- "required": false
- },
- {
- "id": "biomesoplenty:tropics",
- "required": false
- },
- {
- "id": "biomesoplenty:volcanic_plains",
- "required": false
- },
- {
- "id": "biomesoplenty:volcano",
- "required": false
- },
- {
- "id": "biomesoplenty:wasteland",
- "required": false
- },
- {
- "id": "biomesoplenty:erupting_inferno",
- "required": false
- }
- ]
-}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_cold_surface.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_cold_surface.json
index 54c3ccc8..97aa47ea 100644
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_cold_surface.json
+++ b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_cold_surface.json
@@ -7,8 +7,6 @@
"minecraft:taiga",
"minecraft:old_growth_pine_taiga",
"minecraft:old_growth_spruce_taiga",
- "minecraft:windswept_hills",
- "minecraft:windswept_gravelly_hills",
"minecraft:grove",
"minecraft:snowy_slopes",
{
@@ -60,20 +58,14 @@
"required": false
},
{
- "id": "biomesoplenty:coniferous_forest",
+ "id": "biomesoplenty:hot_springs",
"required": false
},
{
- "id": "biomesoplenty:fir_clearing",
+ "id": "biomesoplenty:ominous_woods",
"required": false
},
- {
- "id": "biomesoplenty:seasonal_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:seasonal_orchard",
- "required": false
- }
+ "minecraft:jagged_peaks",
+ "minecraft:frozen_peaks"
]
-}
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_hot_surface.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_hot_surface.json
index 1db1e339..b8d74338 100644
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_hot_surface.json
+++ b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_hot_surface.json
@@ -15,14 +15,6 @@
"id": "biomesoplenty:dryland",
"required": false
},
- {
- "id": "biomesoplenty:dune_beach",
- "required": false
- },
- {
- "id": "biomesoplenty:bayou",
- "required": false
- },
{
"id": "biomesoplenty:fungal_jungle",
"required": false
@@ -48,12 +40,32 @@
"required": false
},
{
- "id": "biomesoplenty:rocky_shrubland",
+ "id": "biomesoplenty:bayou",
"required": false
},
{
- "id": "biomesoplenty:jade_cliffs",
+ "id": "biomesoplenty:lush_desert",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:lush_savanna",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:volcanic_plains",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:volcano",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:wasteland",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:wasteland_steppe",
"required": false
}
]
-}
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_temperate_surface.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_temperate_surface.json
index 1af235c7..7fe27f60 100644
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_temperate_surface.json
+++ b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/latitude_temperate_surface.json
@@ -90,6 +90,64 @@
{
"id": "biomesoplenty:origin_valley",
"required": false
+ },
+ "minecraft:windswept_hills",
+ "minecraft:windswept_gravelly_hills",
+ {
+ "id": "biomesoplenty:seasonal_forest",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:seasonal_orchard",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:prairie",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:coniferous_forest",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:fir_clearing",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:jade_cliffs",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:rocky_shrubland",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:aspen_glade",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:gravel_beach",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:highland",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:jacaranda_glade",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:overgrown_greens",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:pasture",
+ "required": false
+ },
+ {
+ "id": "biomesoplenty:wintry_origin_valley",
+ "required": false
}
]
-}
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/mountain_biomes.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/mountain_biomes.json
index 21c809f0..4d088691 100644
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/mountain_biomes.json
+++ b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/mountain_biomes.json
@@ -4,9 +4,6 @@
"minecraft:jagged_peaks",
"minecraft:frozen_peaks",
"minecraft:stony_peaks",
- "minecraft:savanna_plateau",
- "minecraft:wooded_badlands",
- "minecraft:meadow",
"minecraft:grove",
"minecraft:snowy_slopes",
{
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/rare_biomes.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/rare_biomes.json
index c4b7c6b9..669e7fe9 100644
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/rare_biomes.json
+++ b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/rare_biomes.json
@@ -3,7 +3,6 @@
"values": [
"minecraft:mushroom_fields",
"minecraft:sparse_jungle",
- "minecraft:savanna_plateau",
"minecraft:sunflower_plains",
"minecraft:windswept_gravelly_hills",
"minecraft:flower_forest",
diff --git a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/tempered_biomes.json b/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/tempered_biomes.json
deleted file mode 100644
index 228ca0a5..00000000
--- a/src/main/resources/data/custom_ore_gen/tags/worldgen/biome/tempered_biomes.json
+++ /dev/null
@@ -1,109 +0,0 @@
-{
- "replace": false,
- "values": [
- "minecraft:plains",
- "minecraft:meadow",
- "minecraft:sunflower_plains",
- "minecraft:forest",
- "minecraft:birch_forest",
- "minecraft:swamp",
- "minecraft:taiga",
- "minecraft:old_growth_pine_taiga",
- "minecraft:river",
- "minecraft:beach",
- "minecraft:stony_shore",
- "minecraft:ocean",
- "minecraft:lukewarm_ocean",
- "minecraft:deep_ocean",
- "minecraft:deep_lukewarm_ocean",
- "minecraft:dripstone_caves",
- "minecraft:lush_caves",
- {
- "id": "biomesoplenty:coniferous_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:fir_clearing",
- "required": false
- },
- {
- "id": "biomesoplenty:field",
- "required": false
- },
- {
- "id": "biomesoplenty:forested_field",
- "required": false
- },
- {
- "id": "biomesoplenty:seasonal_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:seasonal_orchard",
- "required": false
- },
- {
- "id": "biomesoplenty:pumpkin_patch",
- "required": false
- },
- {
- "id": "biomesoplenty:grassland",
- "required": false
- },
- {
- "id": "biomesoplenty:spider_nest",
- "required": false
- },
- {
- "id": "biomesoplenty:moor",
- "required": false
- },
- {
- "id": "biomesoplenty:origin_valley",
- "required": false
- },
- {
- "id": "biomesoplenty:shrubland",
- "required": false
- },
- {
- "id": "biomesoplenty:wetland",
- "required": false
- },
- {
- "id": "biomesoplenty:clover_patch",
- "required": false
- },
- {
- "id": "biomesoplenty:redwood_forest",
- "required": false
- },
- {
- "id": "biomesoplenty:rocky_shrubland",
- "required": false
- },
- {
- "id": "biomesoplenty:scrubland",
- "required": false
- },
- {
- "id": "biomesoplenty:woodland",
- "required": false
- },
- {
- "id": "biomesoplenty:old_growth_woodland",
- "required": false
- },
- {
- "id": "biomesoplenty:marsh",
- "required": false
- },
- {
- "id": "biomesoplenty:undergrowth",
- "required": false
- },
- "minecraft:cherry_grove",
- "minecraft:windswept_hills",
- "minecraft:windswept_forest"
- ]
-}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/concentratedcoalore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/concentratedcoalore.json
index ea47dcce..2ce236b2 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/concentratedcoalore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/concentratedcoalore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:concentratedcoalore"
+ "Name": "minecraft:coal_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperhighore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperhighore.json
index 29e9537b..cc7e74df 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperhighore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperhighore.json
@@ -7,12 +7,21 @@
{
"target": {
"predicate_type": "tag_match",
- "tag": "c:stones"
+ "tag": "minecraft:stone_ore_replaceables"
},
"state": {
- "Name": "custom_ore_gen:copperhighore"
+ "Name": "minecraft:copper_ore"
+ }
+ },
+ {
+ "target": {
+ "predicate_type": "tag_match",
+ "tag": "minecraft:deepslate_ore_replaceables"
+ },
+ "state": {
+ "Name": "minecraft:deepslate_copper_ore"
}
}
]
}
-}
\ No newline at end of file
+}
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperlowerore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperlowerore.json
index 721b84e4..d3eb4720 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperlowerore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/copperlowerore.json
@@ -7,12 +7,21 @@
{
"target": {
"predicate_type": "tag_match",
- "tag": "c:stones"
+ "tag": "minecraft:stone_ore_replaceables"
},
"state": {
- "Name": "custom_ore_gen:copperlowerore"
+ "Name": "minecraft:copper_ore"
+ }
+ },
+ {
+ "target": {
+ "predicate_type": "tag_match",
+ "tag": "minecraft:deepslate_ore_replaceables"
+ },
+ "state": {
+ "Name": "minecraft:deepslate_copper_ore"
}
}
]
}
-}
\ No newline at end of file
+}
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatediamondore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatediamondore.json
index 11bacd17..b85e10e7 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatediamondore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatediamondore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:deepslatediamondore"
+ "Name": "minecraft:deepslate_diamond_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateironore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateironore.json
index a9509ac5..e8e2f13a 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateironore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateironore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:deepslateironore"
+ "Name": "minecraft:deepslate_iron_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatelapisore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatelapisore.json
index d340845e..4763089a 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatelapisore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatelapisore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:deepslatelapisore"
+ "Name": "minecraft:deepslate_lapis_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatepuregoldenore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatepuregoldenore.json
index 1e0e12a4..59080bd3 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatepuregoldenore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslatepuregoldenore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:deepslatepuregoldenore"
+ "Name": "minecraft:deepslate_gold_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateredstoneore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateredstoneore.json
index 19666e6d..ad515f0b 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateredstoneore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/deepslateredstoneore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:deepslateredstoneore"
+ "Name": "minecraft:deepslate_redstone_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/highemeraldore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/highemeraldore.json
index f21a7979..15743902 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/highemeraldore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/highemeraldore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:highemeraldore"
+ "Name": "minecraft:emerald_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/ironore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/ironore.json
index 24a62efe..e1ade1f0 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/ironore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/ironore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:ironore"
+ "Name": "minecraft:iron_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/lapisore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/lapisore.json
index ca8739b7..87ae677b 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/lapisore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/lapisore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:lapisore"
+ "Name": "minecraft:lapis_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/loweremeraldore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/loweremeraldore.json
index 9d954666..15743902 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/loweremeraldore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/loweremeraldore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:loweremeraldore"
+ "Name": "minecraft:emerald_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/puregoldenore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/puregoldenore.json
index 071dd436..227da301 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/puregoldenore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/puregoldenore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:puregoldenore"
+ "Name": "minecraft:gold_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/redstoneore.json b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/redstoneore.json
index 206c8e58..5b9eabc4 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/redstoneore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/configured_feature/redstoneore.json
@@ -10,7 +10,7 @@
"tag": "c:stones"
},
"state": {
- "Name": "custom_ore_gen:redstoneore"
+ "Name": "minecraft:redstone_ore"
}
}
]
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_signal.json b/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_signal.json
new file mode 100644
index 00000000..e96d9395
--- /dev/null
+++ b/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_signal.json
@@ -0,0 +1,3 @@
+{
+ "type": "custom_ore_gen:latitude_signal"
+}
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_temperature.json b/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_temperature.json
new file mode 100644
index 00000000..4efe4469
--- /dev/null
+++ b/src/main/resources/data/custom_ore_gen/worldgen/density_function/latitude_temperature.json
@@ -0,0 +1,22 @@
+{
+ "type": "minecraft:clamp",
+ "input": {
+ "type": "minecraft:add",
+ "argument1": "custom_ore_gen:latitude_signal",
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": 0.15,
+ "argument2": {
+ "type": "minecraft:shifted_noise",
+ "noise": "minecraft:temperature",
+ "shift_x": "minecraft:shift_x",
+ "shift_y": 0.0,
+ "shift_z": "minecraft:shift_z",
+ "xz_scale": 0.04,
+ "y_scale": 0.0
+ }
+ }
+ },
+ "min": -1.0,
+ "max": 1.0
+}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/concentratedcoalore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/concentratedcoalore.json
index cb7d3226..7fc57830 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/concentratedcoalore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/concentratedcoalore.json
@@ -3,7 +3,7 @@
"placement": [
{
"type": "minecraft:count",
- "count": 10
+ "count": 20
},
{
"type": "minecraft:in_square"
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "temperate"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperhighore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperhighore.json
index 345e33e0..f5e4a0ab 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperhighore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperhighore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperlowerore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperlowerore.json
index b0789f82..00383563 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperlowerore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/copperlowerore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatediamondore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatediamondore.json
index 5fc6f58d..4e60ba82 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatediamondore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatediamondore.json
@@ -3,7 +3,7 @@
"placement": [
{
"type": "minecraft:count",
- "count": 6
+ "count": 3
},
{
"type": "minecraft:in_square"
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "cold"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateironore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateironore.json
index 218d6fcb..ea2c3dc3 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateironore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateironore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "temperate"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatelapisore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatelapisore.json
index 97126226..83ff1a40 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatelapisore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatelapisore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "cold"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatepuregoldenore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatepuregoldenore.json
index c8e8c922..5b50a17b 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatepuregoldenore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslatepuregoldenore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateredstoneore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateredstoneore.json
index 7f46fa33..6f1cb79c 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateredstoneore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/deepslateredstoneore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/ironore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/ironore.json
index f6e9a1ab..6873cc2b 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/ironore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/ironore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "temperate"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/lapisore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/lapisore.json
index b889f000..f2dfa78f 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/lapisore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/lapisore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "cold"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/puregoldenore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/puregoldenore.json
index 3a79387a..c6075fb9 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/puregoldenore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/puregoldenore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/redstoneore.json b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/redstoneore.json
index 42c87ea7..74fafb6c 100644
--- a/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/redstoneore.json
+++ b/src/main/resources/data/custom_ore_gen/worldgen/placed_feature/redstoneore.json
@@ -21,7 +21,8 @@
}
},
{
- "type": "minecraft:biome"
+ "type": "custom_ore_gen:latitude_zone",
+ "zone": "hot"
}
]
}
\ No newline at end of file
diff --git a/src/main/resources/data/custom_ore_gen/worldgen/world_preset/ultra_wide_biome.json b/src/main/resources/data/custom_ore_gen/worldgen/world_preset/ultra_wide_biome.json
deleted file mode 100644
index 396a5168..00000000
--- a/src/main/resources/data/custom_ore_gen/worldgen/world_preset/ultra_wide_biome.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "dimensions": {
- "minecraft:overworld": {
- "type": "minecraft:overworld",
- "generator": {
- "type": "minecraft:noise",
- "biome_source": {
- "type": "custom_ore_gen:latitude",
- "seed": 0
- },
- "settings": "minecraft:large_biomes"
- }
- },
- "minecraft:the_nether": {
- "type": "minecraft:the_nether",
- "generator": {
- "type": "minecraft:noise",
- "biome_source": {
- "type": "minecraft:multi_noise",
- "preset": "minecraft:nether"
- },
- "settings": "minecraft:nether"
- }
- },
- "minecraft:the_end": {
- "type": "minecraft:the_end",
- "generator": {
- "type": "minecraft:noise",
- "biome_source": {
- "type": "minecraft:the_end"
- },
- "settings": "minecraft:end"
- }
- }
- }
-}
diff --git a/src/main/resources/data/minecraft/tags/worldgen/world_preset/normal.json b/src/main/resources/data/minecraft/tags/worldgen/world_preset/normal.json
deleted file mode 100644
index f2cdb504..00000000
--- a/src/main/resources/data/minecraft/tags/worldgen/world_preset/normal.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "replace": false,
- "values": [
- "minecraft:normal",
- "minecraft:flat",
- "minecraft:large_biomes",
- "minecraft:amplified",
- "minecraft:single_biome_surface",
- "custom_ore_gen:ultra_wide_biome"
- ]
-}
diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json b/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json
new file mode 100644
index 00000000..fde23d65
--- /dev/null
+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/large_biomes.json
@@ -0,0 +1,2473 @@
+{
+ "aquifers_enabled": true,
+ "default_block": {
+ "Name": "minecraft:stone"
+ },
+ "default_fluid": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ },
+ "disable_mob_generation": false,
+ "legacy_random_source": false,
+ "noise": {
+ "height": 576,
+ "min_y": -64,
+ "size_horizontal": 1,
+ "size_vertical": 2
+ },
+ "noise_router": {
+ "barrier": {
+ "type": "range_choice",
+ "min_inclusive": -1.3,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_barrier",
+ "xz_scale": 0.8,
+ "y_scale": 0.7
+ },
+ "when_out_of_range": -1.0
+ },
+ "continents": "minecraft:overworld/continents",
+ "depth": "lithosphere:depth",
+ "erosion": "minecraft:overworld/erosion",
+ "final_density": "lithosphere:density/final_density",
+ "fluid_level_floodedness": {
+ "type": "range_choice",
+ "min_inclusive": 1.7,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_fluid_level_floodedness",
+ "xz_scale": 0.8,
+ "y_scale": 0.67
+ },
+ "when_out_of_range": 0.8
+ },
+ "fluid_level_spread": {
+ "type": "range_choice",
+ "min_inclusive": 3.9,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "noise",
+ "noise": "minecraft:aquifer_fluid_level_spread",
+ "xz_scale": 0.4,
+ "y_scale": 0.714
+ },
+ "when_out_of_range": -0.55
+ },
+ "initial_density_without_jaggedness": {
+ "type": "minecraft:add",
+ "argument1": 0.1171875,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": {
+ "type": "minecraft:y_clamped_gradient",
+ "from_value": 0.0,
+ "from_y": -64,
+ "to_value": 1.0,
+ "to_y": -40
+ },
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": -0.1171875,
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": -0.078125,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": {
+ "type": "minecraft:y_clamped_gradient",
+ "from_value": 1.0,
+ "from_y": 496,
+ "to_value": 0.0,
+ "to_y": 512
+ },
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": 0.078125,
+ "argument2": {
+ "type": "minecraft:clamp",
+ "input": {
+ "type": "minecraft:add",
+ "argument1": -0.703125,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": 4.0,
+ "argument2": {
+ "type": "minecraft:quarter_negative",
+ "argument": {
+ "type": "minecraft:mul",
+ "argument1": "lithosphere:depth",
+ "argument2": {
+ "type": "minecraft:cache_2d",
+ "argument": "minecraft:overworld/factor"
+ }
+ }
+ }
+ }
+ },
+ "max": 64.0,
+ "min": -64.0
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "lava": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_lava",
+ "xz_scale": 0.1,
+ "y_scale": 0.2
+ },
+ "ridges": "minecraft:overworld/ridges",
+ "temperature": "custom_ore_gen:latitude_temperature",
+ "vegetation": {
+ "type": "minecraft:shifted_noise",
+ "noise": "minecraft:vegetation",
+ "shift_x": "minecraft:shift_x",
+ "shift_y": 0.0,
+ "shift_z": "minecraft:shift_z",
+ "xz_scale": 0.05,
+ "y_scale": 0.0
+ },
+ "vein_gap": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_gap",
+ "xz_scale": 1.0,
+ "y_scale": 1.0
+ },
+ "vein_ridged": {
+ "type": "minecraft:add",
+ "argument1": -0.07999999821186066,
+ "argument2": {
+ "type": "minecraft:max",
+ "argument1": {
+ "type": "minecraft:abs",
+ "argument": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_vein_a",
+ "xz_scale": 4.0,
+ "y_scale": 4.0
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ },
+ "argument2": {
+ "type": "minecraft:abs",
+ "argument": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_vein_b",
+ "xz_scale": 4.0,
+ "y_scale": 4.0
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ }
+ }
+ },
+ "vein_toggle": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_veininess",
+ "xz_scale": 1.5,
+ "y_scale": 1.5
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ },
+ "ore_veins_enabled": true,
+ "sea_level": 63,
+ "spawn_target": [
+ {
+ "continentalness": [
+ 0.0,
+ 1.0
+ ],
+ "depth": 0.0,
+ "erosion": [
+ -1.0,
+ 1.0
+ ],
+ "humidity": [
+ -1.0,
+ 1.0
+ ],
+ "offset": 0.0,
+ "temperature": [
+ -1.0,
+ 1.0
+ ],
+ "weirdness": [
+ -1.0,
+ -0.16
+ ]
+ },
+ {
+ "continentalness": [
+ 0.0,
+ 1.0
+ ],
+ "depth": 0.0,
+ "erosion": [
+ -1.0,
+ 1.0
+ ],
+ "humidity": [
+ -1.0,
+ 1.0
+ ],
+ "offset": 0.0,
+ "temperature": [
+ -1.0,
+ 1.0
+ ],
+ "weirdness": [
+ 0.16,
+ 1.0
+ ]
+ }
+ ],
+ "surface_rule": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:vertical_gradient",
+ "false_at_and_above": {
+ "above_bottom": 5
+ },
+ "random_name": "minecraft:bedrock_floor",
+ "true_at_and_below": {
+ "above_bottom": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:bedrock"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:above_preliminary_surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:wooded_badlands"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 97
+ },
+ "surface_depth_multiplier": 2
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": -0.5454,
+ "min_threshold": -0.909,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.1818,
+ "min_threshold": -0.1818,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.909,
+ "min_threshold": 0.5454,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 62
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.0,
+ "noise": "minecraft:surface_swamp"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 60
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.0,
+ "noise": "minecraft:surface_swamp"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:badlands",
+ "minecraft:eroded_badlands",
+ "minecraft:wooded_badlands"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 256
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 74
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": -0.5454,
+ "min_threshold": -0.909,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.1818,
+ "min_threshold": -0.1818,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.909,
+ "min_threshold": 0.5454,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:bandlands"
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": -1,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:red_sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:red_sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:hole"
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:white_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 74
+ },
+ "surface_depth_multiplier": 1
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:bandlands"
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:white_terracotta"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": -1,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_ocean",
+ "minecraft:deep_frozen_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:hole"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:air"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:temperature"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.2,
+ "min_threshold": 0.0,
+ "noise": "minecraft:packed_ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.025,
+ "min_threshold": 0.0,
+ "noise": "minecraft:ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:snowy_slopes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.6,
+ "min_threshold": 0.35,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:grove"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.6,
+ "min_threshold": 0.35,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.0125,
+ "min_threshold": -0.0125,
+ "noise": "minecraft:calcite"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:calcite"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_shore"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.05,
+ "min_threshold": -0.05,
+ "noise": "minecraft:gravel"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 65
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:dripstone_caves"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_savanna"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.06060606060606061,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_gravelly_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.24242424242424243,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:old_growth_pine_taiga",
+ "minecraft:old_growth_spruce_taiga"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.11515151515151514,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:podzol",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:ice_spikes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mud"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mushroom_fields"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mycelium",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_ocean",
+ "minecraft:deep_frozen_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:hole"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.2,
+ "min_threshold": -0.5,
+ "noise": "minecraft:packed_ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.025,
+ "min_threshold": -0.0625,
+ "noise": "minecraft:ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:snowy_slopes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.58,
+ "min_threshold": 0.45,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:grove"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.58,
+ "min_threshold": 0.45,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.0125,
+ "min_threshold": -0.0125,
+ "noise": "minecraft:calcite"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:calcite"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_shore"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.05,
+ "min_threshold": -0.05,
+ "noise": "minecraft:gravel"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 65
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:dripstone_caves"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_savanna"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_gravelly_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.24242424242424243,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mud"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 6,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 30,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks",
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:lukewarm_ocean",
+ "minecraft:deep_lukewarm_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:vertical_gradient",
+ "false_at_and_above": {
+ "absolute": 8
+ },
+ "random_name": "minecraft:deepslate",
+ "true_at_and_below": {
+ "absolute": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:deepslate",
+ "Properties": {
+ "axis": "y"
+ }
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json
new file mode 100644
index 00000000..230d0fbc
--- /dev/null
+++ b/src/main/resources/data/minecraft/worldgen/noise_settings/overworld.json
@@ -0,0 +1,2535 @@
+{
+ "aquifers_enabled": true,
+ "default_block": {
+ "Name": "minecraft:stone"
+ },
+ "default_fluid": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ },
+ "disable_mob_generation": false,
+ "legacy_random_source": false,
+ "noise": {
+ "height": 576,
+ "min_y": -64,
+ "size_horizontal": 1,
+ "size_vertical": 2
+ },
+ "noise_router": {
+ "barrier": {
+ "type": "range_choice",
+ "min_inclusive": -1.3,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_barrier",
+ "xz_scale": 0.8,
+ "y_scale": 0.7
+ },
+ "when_out_of_range": -1.0
+ },
+ "continents": "minecraft:overworld/continents",
+ "depth": "lithosphere:depth",
+ "erosion": "minecraft:overworld/erosion",
+ "final_density": "lithosphere:density/final_density",
+ "fluid_level_floodedness": {
+ "type": "range_choice",
+ "min_inclusive": 1.7,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_fluid_level_floodedness",
+ "xz_scale": 0.8,
+ "y_scale": 0.67
+ },
+ "when_out_of_range": 0.8
+ },
+ "fluid_level_spread": {
+ "type": "range_choice",
+ "min_inclusive": 3.9,
+ "max_exclusive": 10,
+ "input": "lithosphere:caves/underground_rivers",
+ "when_in_range": {
+ "type": "noise",
+ "noise": "minecraft:aquifer_fluid_level_spread",
+ "xz_scale": 0.4,
+ "y_scale": 0.714
+ },
+ "when_out_of_range": -0.55
+ },
+ "initial_density_without_jaggedness": {
+ "type": "minecraft:add",
+ "argument1": 0.1171875,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": {
+ "type": "minecraft:y_clamped_gradient",
+ "from_value": 0.0,
+ "from_y": -64,
+ "to_value": 1.0,
+ "to_y": -40
+ },
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": -0.1171875,
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": -0.078125,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": {
+ "type": "minecraft:y_clamped_gradient",
+ "from_value": 1.0,
+ "from_y": 496,
+ "to_value": 0.0,
+ "to_y": 512
+ },
+ "argument2": {
+ "type": "minecraft:add",
+ "argument1": 0.078125,
+ "argument2": {
+ "type": "minecraft:clamp",
+ "input": {
+ "type": "minecraft:add",
+ "argument1": -0.703125,
+ "argument2": {
+ "type": "minecraft:mul",
+ "argument1": 4.0,
+ "argument2": {
+ "type": "minecraft:quarter_negative",
+ "argument": {
+ "type": "minecraft:mul",
+ "argument1": "lithosphere:depth",
+ "argument2": {
+ "type": "minecraft:cache_2d",
+ "argument": "minecraft:overworld/factor"
+ }
+ }
+ }
+ }
+ },
+ "max": 64.0,
+ "min": -64.0
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "lava": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:aquifer_lava",
+ "xz_scale": 0.1,
+ "y_scale": 0.2
+ },
+ "ridges": "minecraft:overworld/ridges",
+ "temperature": "custom_ore_gen:latitude_temperature",
+ "vegetation": {
+ "type": "minecraft:shifted_noise",
+ "noise": "minecraft:vegetation",
+ "shift_x": "minecraft:shift_x",
+ "shift_y": 0.0,
+ "shift_z": "minecraft:shift_z",
+ "xz_scale": 0.125,
+ "y_scale": 0.0
+ },
+ "vein_gap": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_gap",
+ "xz_scale": 1.0,
+ "y_scale": 1.0
+ },
+ "vein_ridged": {
+ "type": "minecraft:add",
+ "argument1": -0.07999999821186066,
+ "argument2": {
+ "type": "minecraft:max",
+ "argument1": {
+ "type": "minecraft:abs",
+ "argument": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_vein_a",
+ "xz_scale": 4.0,
+ "y_scale": 4.0
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ },
+ "argument2": {
+ "type": "minecraft:abs",
+ "argument": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_vein_b",
+ "xz_scale": 4.0,
+ "y_scale": 4.0
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ }
+ }
+ },
+ "vein_toggle": {
+ "type": "minecraft:interpolated",
+ "argument": {
+ "type": "minecraft:range_choice",
+ "input": "minecraft:y",
+ "max_exclusive": 51.0,
+ "min_inclusive": -60.0,
+ "when_in_range": {
+ "type": "minecraft:noise",
+ "noise": "minecraft:ore_veininess",
+ "xz_scale": 1.5,
+ "y_scale": 1.5
+ },
+ "when_out_of_range": 0.0
+ }
+ }
+ },
+ "ore_veins_enabled": true,
+ "sea_level": 63,
+ "spawn_target": [
+ {
+ "continentalness": [
+ 0.1,
+ 1.0
+ ],
+ "depth": 0.0,
+ "erosion": [
+ -1.0,
+ 1.0
+ ],
+ "humidity": [
+ -1.0,
+ 1.0
+ ],
+ "offset": 0.0,
+ "temperature": [
+ -1.0,
+ 1.0
+ ],
+ "weirdness": [
+ -1.0,
+ -0.16
+ ]
+ },
+ {
+ "continentalness": [
+ 0.1,
+ 1.0
+ ],
+ "depth": 0.0,
+ "erosion": [
+ -1.0,
+ 1.0
+ ],
+ "humidity": [
+ -1.0,
+ 1.0
+ ],
+ "offset": 0.0,
+ "temperature": [
+ -1.0,
+ 1.0
+ ],
+ "weirdness": [
+ 0.16,
+ 1.0
+ ]
+ }
+ ],
+ "surface_rule": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:vertical_gradient",
+ "false_at_and_above": {
+ "above_bottom": 5
+ },
+ "random_name": "minecraft:bedrock_floor",
+ "true_at_and_below": {
+ "above_bottom": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:bedrock"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:above_preliminary_surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:wooded_badlands"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 97
+ },
+ "surface_depth_multiplier": 2
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": -0.5454,
+ "min_threshold": -0.909,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.1818,
+ "min_threshold": -0.1818,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.909,
+ "min_threshold": 0.5454,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 62
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.0,
+ "noise": "minecraft:surface_swamp"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 60
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.0,
+ "noise": "minecraft:surface_swamp"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:badlands",
+ "minecraft:eroded_badlands",
+ "minecraft:wooded_badlands"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 256
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 74
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": -0.5454,
+ "min_threshold": -0.909,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.1818,
+ "min_threshold": -0.1818,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.909,
+ "min_threshold": 0.5454,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:bandlands"
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": -1,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:red_sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:red_sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:hole"
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:white_terracotta"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": true,
+ "anchor": {
+ "absolute": 74
+ },
+ "surface_depth_multiplier": 1
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:orange_terracotta"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:bandlands"
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:white_terracotta"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": -1,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_ocean",
+ "minecraft:deep_frozen_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:hole"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:air"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:temperature"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.2,
+ "min_threshold": 0.0,
+ "noise": "minecraft:packed_ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.025,
+ "min_threshold": 0.0,
+ "noise": "minecraft:ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:snowy_slopes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.6,
+ "min_threshold": 0.35,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:grove"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.6,
+ "min_threshold": 0.35,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.0125,
+ "min_threshold": -0.0125,
+ "noise": "minecraft:calcite"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:calcite"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_shore"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 1
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.05,
+ "min_threshold": -0.05,
+ "noise": "minecraft:gravel"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 65
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:dripstone_caves"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_savanna"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.06060606060606061,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_gravelly_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.24242424242424243,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:old_growth_pine_taiga",
+ "minecraft:old_growth_spruce_taiga"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:coarse_dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.11515151515151514,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:podzol",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:ice_spikes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mud"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mushroom_fields"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mycelium",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:grass_block",
+ "Properties": {
+ "snowy": "false"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": true,
+ "offset": -6,
+ "surface_depth_multiplier": -1
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_ocean",
+ "minecraft:deep_frozen_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:hole"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:water",
+ "Properties": {
+ "level": "0"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.2,
+ "min_threshold": -0.5,
+ "noise": "minecraft:packed_ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:packed_ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.025,
+ "min_threshold": -0.0625,
+ "noise": "minecraft:ice"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:ice"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:snowy_slopes"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:steep"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.58,
+ "min_threshold": 0.45,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:snow_block"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:grove"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.58,
+ "min_threshold": 0.45,
+ "noise": "minecraft:powder_snow"
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:water",
+ "add_stone_depth": false,
+ "offset": 0,
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:powder_snow"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.0125,
+ "min_threshold": -0.0125,
+ "noise": "minecraft:calcite"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:calcite"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:stony_shore"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:not",
+ "invert": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 63
+ },
+ "surface_depth_multiplier": 1
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 0.05,
+ "min_threshold": -0.05,
+ "noise": "minecraft:gravel"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 10
+ },
+ "surface_depth_multiplier": 0
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:y_above",
+ "add_stone_depth": false,
+ "anchor": {
+ "absolute": 65
+ },
+ "surface_depth_multiplier": 1
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:dripstone_caves"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_savanna"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.21212121212121213,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:windswept_gravelly_hills"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.24242424242424243,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": 0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:noise_threshold",
+ "max_threshold": 1.7976931348623157e+308,
+ "min_threshold": -0.12121212121212122,
+ "noise": "minecraft:surface"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:mangrove_swamp"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:mud"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:dirt"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:beach",
+ "minecraft:snowy_beach"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 6,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:desert"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": true,
+ "offset": 0,
+ "secondary_depth_range": 30,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "floor"
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:frozen_peaks",
+ "minecraft:jagged_peaks"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:biome",
+ "biome_is": [
+ "minecraft:warm_ocean",
+ "minecraft:lukewarm_ocean",
+ "minecraft:deep_lukewarm_ocean"
+ ]
+ },
+ "then_run": {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sandstone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:sand"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:sequence",
+ "sequence": [
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:stone_depth",
+ "add_surface_depth": false,
+ "offset": 0,
+ "secondary_depth_range": 0,
+ "surface_type": "ceiling"
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:stone"
+ }
+ }
+ },
+ {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:gravel"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "minecraft:condition",
+ "if_true": {
+ "type": "minecraft:vertical_gradient",
+ "false_at_and_above": {
+ "absolute": 8
+ },
+ "random_name": "minecraft:deepslate",
+ "true_at_and_below": {
+ "absolute": 0
+ }
+ },
+ "then_run": {
+ "type": "minecraft:block",
+ "result_state": {
+ "Name": "minecraft:deepslate",
+ "Properties": {
+ "axis": "y"
+ }
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/net/mcreator/customoregen/worldgen/BiomeBandTest.java b/src/test/java/net/mcreator/customoregen/worldgen/BiomeBandTest.java
deleted file mode 100644
index 338e65c6..00000000
--- a/src/test/java/net/mcreator/customoregen/worldgen/BiomeBandTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import net.minecraft.world.level.biome.Biomes;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * Pure unit tests for {@link BiomeBand}, the climate-band logic that drives
- * {@link LatitudeBiomeSource}.
- *
- * These tests run as plain JUnit (no game server required): {@code fromTemperature}
- * is a pure function of a double, and the {@code surfaceVanilla}/{@code ocean}/
- * {@code surfaceTag} helpers only ever touch {@link net.minecraft.resources.ResourceKey}
- * and {@link net.minecraft.tags.TagKey} objects, which are pure value types that
- * never consult a live registry. They therefore protect the most important
- * behaviour of the latitude system without needing {@code runGameTestServer}.
- */
-@DisplayName("BiomeBand climate logic")
-class BiomeBandTest {
-
- // ------------------------------------------------------------------
- // fromTemperature: boundary conditions
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("FROZEN at the extreme cold pole")
- void fromTemperature_frozenAtExtremeCold() {
- assertEquals(BiomeBand.FROZEN, BiomeBand.fromTemperature(-1.0));
- assertEquals(BiomeBand.FROZEN, BiomeBand.fromTemperature(-0.9));
- }
-
- @Test
- @DisplayName("-0.7 boundary is FROZEN (inclusive: <=)")
- void fromTemperature_boundaryMinus07_isFrozenInclusive() {
- assertEquals(BiomeBand.FROZEN, BiomeBand.fromTemperature(-0.7));
- }
-
- @Test
- @DisplayName("just above -0.7 is COLD")
- void fromTemperature_justAboveMinus07_isCold() {
- assertEquals(BiomeBand.COLD, BiomeBand.fromTemperature(-0.69));
- assertEquals(BiomeBand.COLD, BiomeBand.fromTemperature(-0.5));
- }
-
- @Test
- @DisplayName("-0.25 boundary is COLD (inclusive: <=)")
- void fromTemperature_boundaryMinus025_isColdInclusive() {
- assertEquals(BiomeBand.COLD, BiomeBand.fromTemperature(-0.25));
- }
-
- @Test
- @DisplayName("just above -0.25 is TEMPERATE")
- void fromTemperature_justAboveMinus025_isTemperate() {
- assertEquals(BiomeBand.TEMPERATE, BiomeBand.fromTemperature(-0.24));
- assertEquals(BiomeBand.TEMPERATE, BiomeBand.fromTemperature(0.0));
- assertEquals(BiomeBand.TEMPERATE, BiomeBand.fromTemperature(0.2499));
- }
-
- @Test
- @DisplayName("+0.25 boundary is WARM (TEMPERATE uses strict <)")
- void fromTemperature_at025_isWarm_boundaryNotInclusive() {
- assertEquals(BiomeBand.WARM, BiomeBand.fromTemperature(0.25));
- assertEquals(BiomeBand.WARM, BiomeBand.fromTemperature(0.5));
- }
-
- @Test
- @DisplayName("+0.7 boundary and above is HOT")
- void fromTemperature_atAndAbove07_isHot() {
- assertEquals(BiomeBand.HOT, BiomeBand.fromTemperature(0.7));
- assertEquals(BiomeBand.HOT, BiomeBand.fromTemperature(0.9));
- assertEquals(BiomeBand.HOT, BiomeBand.fromTemperature(1.0));
- }
-
- @Test
- @DisplayName("fromTemperature never returns null across the full range")
- void fromTemperature_neverReturnsNull() {
- double[] temps = {-1.0, -0.95, -0.71, -0.7, -0.69, -0.5, -0.3, -0.26, -0.25,
- -0.24, -0.1, 0.0, 0.1, 0.2499, 0.25, 0.3, 0.5, 0.6999,
- 0.7, 0.8, 0.95, 1.0};
- for (double t : temps) {
- assertNotNull(BiomeBand.fromTemperature(t),
- "fromTemperature must never return null for t=" + t);
- }
- }
-
- @Test
- @DisplayName("surface temperature 0.0 (equator / spawn) is TEMPERATE")
- void fromTemperature_equatorIsTemperate() {
- // The spawn safe zone sits around Z=0, i.e. temperature 0 -> TEMPERATE.
- assertEquals(BiomeBand.TEMPERATE, BiomeBand.fromTemperature(0.0));
- }
-
- // ------------------------------------------------------------------
- // Band metadata invariants
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("band center temperatures are strictly increasing from pole to pole")
- void bandsCenterTemperaturesAreMonotonic() {
- BiomeBand[] bands = BiomeBand.values();
- for (int i = 1; i < bands.length; i++) {
- assertTrue(bands[i - 1].centerTemperature < bands[i].centerTemperature,
- "Band centers must be strictly increasing: "
- + bands[i - 1] + " -> " + bands[i]);
- }
- assertEquals(-1.0, BiomeBand.FROZEN.centerTemperature);
- assertEquals(1.0, BiomeBand.HOT.centerTemperature);
- assertEquals(5, BiomeBand.values().length, "exactly five climate bands expected");
- }
-
- // ------------------------------------------------------------------
- // surfaceTag (must point at the mod's own tags so BoP can extend safely)
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("every band has a non-null surface tag under the mod namespace")
- void surfaceTag_isNotNullAndNamespacedForEveryBand() {
- for (BiomeBand band : BiomeBand.values()) {
- assertNotNull(band.surfaceTag(), "surfaceTag must not be null for " + band);
- assertEquals("custom_ore_gen", band.surfaceTag().location().getNamespace(),
- "surface tag namespace must be the mod id for " + band);
- }
- }
-
- @Test
- @DisplayName("cold/frozen bands share the latitude_cold_surface tag")
- void surfaceTag_frozenAndColdShareColdSurfaceTag() {
- assertEquals(BiomeBand.FROZEN.surfaceTag(),
- BiomeBand.COLD.surfaceTag(),
- "FROZEN and COLD must pull surface biomes from the same cold tag");
- }
-
- @Test
- @DisplayName("warm/hot bands share the latitude_hot_surface tag")
- void surfaceTag_warmAndHotShareHotSurfaceTag() {
- assertEquals(BiomeBand.WARM.surfaceTag(),
- BiomeBand.HOT.surfaceTag(),
- "WARM and HOT must pull surface biomes from the same hot tag");
- }
-
- // ------------------------------------------------------------------
- // surfaceVanilla / ocean pools (must be non-empty for every band)
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("every band has a non-empty vanilla surface pool")
- void surfaceVanilla_isNonEmptyForEveryBand() {
- for (BiomeBand band : BiomeBand.values()) {
- assertFalse(band.surfaceVanilla().isEmpty(),
- "surfaceVanilla pool must not be empty for " + band);
- // Note: List.of (used by surfaceVanilla) already guarantees non-null elements by
- // construction (it throws NPE if any Biomes.X constant were null), so there is
- // no need to assert contains(null) here - and List.of rejects contains(null) too.
- }
- }
-
- @Test
- @DisplayName("every band has a non-empty ocean pool")
- void ocean_isNonEmptyForEveryBand() {
- for (BiomeBand band : BiomeBand.values()) {
- assertFalse(band.ocean().isEmpty(),
- "ocean pool must not be empty for " + band);
- }
- }
-
- @Test
- @DisplayName("PLAINS is in the TEMPERATE surface pool (spawn must be buildable)")
- void surfaceVanilla_plainsIsInTemperatePool() {
- assertTrue(BiomeBand.TEMPERATE.surfaceVanilla().contains(Biomes.PLAINS),
- "PLAINS must be in the TEMPERATE surface pool (spawn safe zone relies on it)");
- }
-
- @Test
- @DisplayName("DESERT is in the HOT surface pool")
- void surfaceVanilla_desertIsInHotPool() {
- assertTrue(BiomeBand.HOT.surfaceVanilla().contains(Biomes.DESERT),
- "DESERT must be in the HOT surface pool");
- }
-
- @Test
- @DisplayName("deepDark-style cave biomes are NOT surfaced in any band")
- void surfaceVanilla_doesNotContainCaveBiomes() {
- // Cave biomes are vanilla-only, eager, injected underground by LatitudeBiomeSource.
- // They must never be in a surface pool.
- for (BiomeBand band : BiomeBand.values()) {
- assertFalse(band.surfaceVanilla().contains(Biomes.DEEP_DARK),
- "DEEP_DARK must never be in the surface pool of " + band);
- assertFalse(band.surfaceVanilla().contains(Biomes.LUSH_CAVES),
- "LUSH_CAVES must never be in the surface pool of " + band);
- assertFalse(band.surfaceVanilla().contains(Biomes.DRIPSTONE_CAVES),
- "DRIPSTONE_CAVES must never be in the surface pool of " + band);
- }
- }
-}
diff --git a/src/test/java/net/mcreator/customoregen/worldgen/LatitudeMathTest.java b/src/test/java/net/mcreator/customoregen/worldgen/LatitudeMathTest.java
deleted file mode 100644
index 639f65c1..00000000
--- a/src/test/java/net/mcreator/customoregen/worldgen/LatitudeMathTest.java
+++ /dev/null
@@ -1,315 +0,0 @@
-package net.mcreator.customoregen.worldgen;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * Pure (registry-free) unit tests for {@link LatitudeMath}, the single source of truth
- * for the latitude world geometry. Because {@link LatitudeBiomeSource} now delegates
- * every climate/zone/index calculation here, these tests cover the geometry the BiomeSource
- * actually uses at runtime - without needing a loaded biome registry.
- */
-@DisplayName("LatitudeMath geometry (temperature, zones, spawn, selection)")
-class LatitudeMathTest {
-
- // ------------------------------------------------------------------
- // Temperature derivation
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("equator (Z=0) has raw temperature 0")
- void rawLatitudeTemperature_equatorIsZero() {
- assertEquals(0.0, LatitudeMath.rawLatitudeTemperature(0), 1e-9);
- }
-
- @Test
- @DisplayName("north pole (Z=-16000) clamps to -1, south pole (Z=+16000) to +1")
- void rawLatitudeTemperature_polesClamp() {
- assertEquals(-1.0, LatitudeMath.rawLatitudeTemperature(-16000), 1e-9);
- assertEquals(1.0, LatitudeMath.rawLatitudeTemperature(16000), 1e-9);
- }
-
- @Test
- @DisplayName("temperature beyond the poles stays clamped to [-1, 1]")
- void rawLatitudeTemperature_extremeClamped() {
- assertEquals(-1.0, LatitudeMath.rawLatitudeTemperature(-1_000_000), 1e-9);
- assertEquals(1.0, LatitudeMath.rawLatitudeTemperature(1_000_000), 1e-9);
- }
-
- @Test
- @DisplayName("temperature is continuous and monotonic in Z (north=cold, south=hot)")
- void rawLatitudeTemperature_monotonic() {
- double tNeg = LatitudeMath.rawLatitudeTemperature(-8000);
- double tZero = LatitudeMath.rawLatitudeTemperature(0);
- double tPos = LatitudeMath.rawLatitudeTemperature(8000);
- assertTrue(tNeg < tZero, "north must be colder than equator: " + tNeg + " < " + tZero);
- assertTrue(tPos > tZero, "south must be warmer than equator: " + tPos + " > " + tZero);
- assertTrue(tNeg < 0, "north must be negative");
- assertTrue(tPos > 0, "south must be positive");
- }
-
- @Test
- @DisplayName("temperature(blockZ, 0 wobble) equals rawLatitudeTemperature(blockZ)")
- void temperature_zeroWobbleMatchesRaw() {
- for (int z : new int[]{-1_000_000, -32000, -16000, -8000, -1, 0, 1, 8000, 16000, 32000, 1_000_000}) {
- assertEquals(LatitudeMath.rawLatitudeTemperature(z), LatitudeMath.temperature(z, 0.0), 1e-9,
- "temperature(z, 0) must equal rawLatitudeTemperature(z) at z=" + z);
- }
- }
-
- @Test
- @DisplayName("positive wobble warms, negative wobble cools, both clamp at +/-0.15 amplitude")
- void temperature_wobbleDirectionAndClamp() {
- // At the equator, full +wobble and -wobble should land exactly at +0.15 / -0.15.
- assertEquals(0.15, LatitudeMath.temperature(0, 0.15), 1e-9);
- assertEquals(-0.15, LatitudeMath.temperature(0, -0.15), 1e-9);
- // At the pole, clamping kicks in: the wobble cannot push past +/-1.
- assertEquals(1.0, LatitudeMath.temperature(16000, 0.5), 1e-9);
- assertEquals(-1.0, LatitudeMath.temperature(-16000, -0.5), 1e-9);
- }
-
- // ------------------------------------------------------------------
- // Underground zone model (3 zones)
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("zone boundaries: deep < -30, mid -30..-1, surface >= 0")
- void zoneForY_boundaries() {
- assertEquals(LatitudeMath.Zone.SURFACE, LatitudeMath.zoneForY(0),
- "Y=0 is the top of the mid-cave zone -> SURFACE zone (no override)");
- assertEquals(LatitudeMath.Zone.SURFACE, LatitudeMath.zoneForY(1));
- assertEquals(LatitudeMath.Zone.SURFACE, LatitudeMath.zoneForY(64));
- assertEquals(LatitudeMath.Zone.SURFACE, LatitudeMath.zoneForY(320));
-
- assertEquals(LatitudeMath.Zone.MID_CAVE, LatitudeMath.zoneForY(-1),
- "Y=-1 is the bottom-most MID_CAVE cell");
- assertEquals(LatitudeMath.Zone.MID_CAVE, LatitudeMath.zoneForY(-15));
- assertEquals(LatitudeMath.Zone.MID_CAVE, LatitudeMath.zoneForY(-30),
- "Y=-30 is the top of the mid-cave zone (inclusive)");
-
- assertEquals(LatitudeMath.Zone.DEEP, LatitudeMath.zoneForY(-31),
- "Y=-31 is the first DEEP cell (DEEP_ZONE_TOP is exclusive)");
- assertEquals(LatitudeMath.Zone.DEEP, LatitudeMath.zoneForY(-50));
- assertEquals(LatitudeMath.Zone.DEEP, LatitudeMath.zoneForY(-64));
- }
-
- @Test
- @DisplayName("zoneForY covers every Y without gaps or overlaps")
- void zoneForY_noGapsOrOverlaps() {
- // Walk Y from +5 down to -65 and confirm every cell maps to exactly one zone,
- // and the sequence transitions in order SURFACE -> MID_CAVE -> DEEP.
- LatitudeMath.Zone prev = null;
- int transitions = 0;
- for (int y = 5; y >= -65; y--) {
- LatitudeMath.Zone z = LatitudeMath.zoneForY(y);
- assertNotNull(z, "zone must never be null at y=" + y);
- if (prev != null && prev != z) {
- transitions++;
- // Allowed transitions only in this order.
- if (prev == LatitudeMath.Zone.SURFACE) {
- assertEquals(LatitudeMath.Zone.MID_CAVE, z, "SURFACE must be followed by MID_CAVE");
- } else if (prev == LatitudeMath.Zone.MID_CAVE) {
- assertEquals(LatitudeMath.Zone.DEEP, z, "MID_CAVE must be followed by DEEP");
- } else {
- fail("unexpected transition out of " + prev);
- }
- }
- prev = z;
- }
- assertEquals(2, transitions, "exactly two zone transitions expected over the Y range");
- }
-
- // ------------------------------------------------------------------
- // Cave pocket + Deep Dark predicate gates
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("isDeepDarkPocket triggers above the threshold only")
- void deepDarkPocket_threshold() {
- assertFalse(LatitudeMath.isDeepDarkPocket(0.0));
- assertFalse(LatitudeMath.isDeepDarkPocket(0.5499));
- assertFalse(LatitudeMath.isDeepDarkPocket(0.55),
- "Deep Dark threshold is strict >, so exactly 0.55 is NOT a pocket");
- assertTrue(LatitudeMath.isDeepDarkPocket(0.55001));
- assertTrue(LatitudeMath.isDeepDarkPocket(1.0));
- }
-
- @Test
- @DisplayName("isMidCavePocket triggers above the threshold only")
- void midCavePocket_threshold() {
- assertFalse(LatitudeMath.isMidCavePocket(0.0));
- assertFalse(LatitudeMath.isMidCavePocket(0.3799));
- assertFalse(LatitudeMath.isMidCavePocket(0.38),
- "cave threshold is strict >, so exactly 0.38 is NOT a pocket");
- assertTrue(LatitudeMath.isMidCavePocket(0.38001));
- assertTrue(LatitudeMath.isMidCavePocket(1.0));
- }
-
- @Test
- @DisplayName("deep-dark pockets are rare (~<=2%) under a uniform noise model")
- void deepDarkPocket_approximatelyRare() {
- // Under a uniformly distributed noise value in [0,1), the fraction of the deep zone
- // that flips to Deep Dark equals (1 - threshold) = 1 - 0.55 = 45%.
- // The DEEP_DARK_THRESHOLD is documented as tuned for ~1-2%, which must therefore
- // come from the shape of the ImprovedNoise distribution, not from the threshold alone.
- // This test pins that contract: the threshold is 0.55, so a uniform sample would give 45%.
- // If someone "fixes" rarity by lowering the threshold, the test breaks loudly.
- int hits = 0;
- int n = 100_000;
- for (int i = 0; i < n; i++) {
- double v = (i + 0.5) / n; // deterministic uniform grid in (0,1)
- if (LatitudeMath.isDeepDarkPocket(v)) hits++;
- }
- assertEquals(0.45, hits / (double) n, 1e-9,
- "threshold 0.55 -> uniform fraction must be 45% (real rarity comes from noise shape)");
- }
-
- // ------------------------------------------------------------------
- // Spawn safe zone
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("origin is inside the spawn safe zone")
- void spawnSafeZone_origin() {
- assertTrue(LatitudeMath.isInSpawnSafeZone(0, 0));
- assertTrue(LatitudeMath.isInSpawnSafeZone(539, 539));
- }
-
- @Test
- @DisplayName("just outside the safe radius is NOT safe")
- void spawnSafeZone_outside() {
- assertFalse(LatitudeMath.isInSpawnSafeZone(540, 0),
- "x=540 equals radius, must be outside (strict <)");
- assertFalse(LatitudeMath.isInSpawnSafeZone(0, 540));
- assertFalse(LatitudeMath.isInSpawnSafeZone(-540, -540));
- assertFalse(LatitudeMath.isInSpawnSafeZone(1000, 1000));
- }
-
- @Test
- @DisplayName("spawn safe zone is a square symmetric around the origin")
- void spawnSafeZone_symmetricSquare() {
- for (int x : new int[]{0, 50, 539, -50, -539}) {
- assertEquals(LatitudeMath.isInSpawnSafeZone(x, 50),
- LatitudeMath.isInSpawnSafeZone(-x, 50),
- "safe zone must be X-symmetric at x=" + x);
- }
- for (int z : new int[]{0, 50, 539, -50, -539}) {
- assertEquals(LatitudeMath.isInSpawnSafeZone(50, z),
- LatitudeMath.isInSpawnSafeZone(50, -z),
- "safe zone must be Z-symmetric at z=" + z);
- }
- }
-
- @Test
- @DisplayName("spawn safe zone edge count matches a 2*radius x 2*radius square (exclusive)")
- void spawnSafeZone_edgeCount() {
- // SPAWN_SAFE_RADIUS = 540, strict <, so the square is [-539, 539] inclusive on both axes.
- int count = 0;
- for (int x = -545; x <= 545; x++) {
- for (int z = -545; z <= 545; z++) {
- if (LatitudeMath.isInSpawnSafeZone(x, z)) count++;
- }
- }
- assertEquals(2 * 539 + 1, (int) Math.sqrt(count),
- "safe zone side length must be 2*(540-1)+1 = 1079");
- assertEquals(1079 * 1079, count);
- }
-
- // ------------------------------------------------------------------
- // Biome selector index math (dual-octave flattening)
- // ------------------------------------------------------------------
-
- @Test
- @DisplayName("normalisedSelector always lands in [0, 1]")
- void normalisedSelector_range() {
- // ImprovedNoise output is roughly in [-1, 1] but can overshoot a little; the normaliser
- // must clamp no matter the input.
- double[] extremeInputs = {-10, -2, -1, -0.5, 0, 0.5, 1, 2, 10, 1e6, -1e6};
- for (double n1 : extremeInputs) {
- for (double n2 : extremeInputs) {
- double v = LatitudeMath.normalisedSelector(n1, n2);
- assertTrue(v >= 0.0 && v <= 1.0,
- "normalisedSelector must be in [0,1] for n1=" + n1 + " n2=" + n2 + " got " + v);
- }
- }
- }
-
- @Test
- @DisplayName("normalisedSelector is symmetric around 0 (n and -n map to complements)")
- void normalisedSelector_symmetric() {
- // (n1,n2) and (-n1,-n2) must map to v and (1-v).
- for (double n1 : new double[]{-0.8, -0.3, 0.0, 0.3, 0.8}) {
- for (double n2 : new double[]{-0.8, -0.3, 0.0, 0.3, 0.8}) {
- double v = LatitudeMath.normalisedSelector(n1, n2);
- double vNeg = LatitudeMath.normalisedSelector(-n1, -n2);
- assertEquals(1.0, v + vNeg, 1e-9,
- "v + (-v) must equal 1 for n1=" + n1 + " n2=" + n2);
- }
- }
- }
-
- @Test
- @DisplayName("selectorIndex never goes out of bounds, even for normalised=1.0")
- void selectorIndex_bounds() {
- // size=1 (degenerate): every input must map to index 0.
- assertEquals(0, LatitudeMath.selectorIndex(0.0, 1));
- assertEquals(0, LatitudeMath.selectorIndex(0.5, 1));
- assertEquals(0, LatitudeMath.selectorIndex(1.0, 1));
-
- // size=4: index in [0,3], and normalised=1.0 must clamp to last, not 4.
- for (double v = 0.0; v <= 1.0001; v += 0.001) {
- int idx = LatitudeMath.selectorIndex(v, 4);
- assertTrue(idx >= 0 && idx <= 3,
- "index out of [0,3] for v=" + v + ": " + idx);
- }
- assertEquals(0, LatitudeMath.selectorIndex(0.0, 4));
- assertEquals(3, LatitudeMath.selectorIndex(1.0, 4));
- assertEquals(3, LatitudeMath.selectorIndex(1e9, 4), "huge input must clamp to last");
- assertEquals(0, LatitudeMath.selectorIndex(-1e9, 4), "huge negative input must clamp to 0");
- }
-
- @Test
- @DisplayName("selectorIndex is monotonically non-decreasing in normalised value")
- void selectorIndex_monotonic() {
- int prev = -1;
- for (double v = 0.0; v <= 1.0; v += 0.0001) {
- int idx = LatitudeMath.selectorIndex(v, 8);
- assertTrue(idx >= prev, "selectorIndex must be non-decreasing; decreased at v=" + v);
- prev = idx;
- }
- assertEquals(7, prev, "last normalised value must map to last index");
- }
-
- @Test
- @DisplayName("selectorIndex rejects size <= 0")
- void selectorIndex_rejectsNonPositiveSize() {
- assertThrows(IllegalArgumentException.class, () -> LatitudeMath.selectorIndex(0.5, 0));
- assertThrows(IllegalArgumentException.class, () -> LatitudeMath.selectorIndex(0.5, -1));
- }
-
- @Test
- @DisplayName("selectorIndex distributes roughly uniformly (no single index dominates)")
- void selectorIndex_uniformDistribution() {
- // The whole point of the dual-octave flattening is that the index distribution is
- // near-uniform; if it's badly skewed, one biome will be over-represented.
- // ImprovedNoise roughly outputs a bell curve in [-1,1], so we sample that.
- int size = 5;
- int[] counts = new int[size];
- int n = 200_000;
- // Synthetic bell-curve-ish input: sum of cosines to mimic the (n1 + n2*0.5)/1.5 shape.
- for (int i = 0; i < n; i++) {
- double t = (i + 0.5) / n * Math.PI;
- double n1 = Math.cos(t * 7.0);
- double n2 = Math.cos(t * 13.0 + 0.3);
- counts[LatitudeMath.selectorIndex(LatitudeMath.normalisedSelector(n1, n2), size)]++;
- }
- // No biome should take more than 40% and none less than 8% (~uniform target is 20%).
- for (int c : counts) {
- double ratio = c / (double) n;
- assertTrue(ratio < 0.40, "a biome index is over-represented: " + ratio);
- assertTrue(ratio > 0.08, "a biome index is under-represented: " + ratio);
- }
- }
-}