Phase 4: veins in every chunk, drops for the mobs the island lacks

Ore veins: make_world.py loads the island again row by row until
Regenerating Ore Veins has filled every chunk (/cobblesurvival veins
unfilled), cave tiers sit at their biome's depths, small zones get denser
veins, showcase veins are full size. The world report checks surface
tiers against the zone grid, cave tiers within two biome cells of their
cave, and fails on unfilled chunks; the template passes (37,689 chunks).

Drops: tools/drop_audit.py checks every creature drop a recipe or brewing
needs (docs/pokemon-drops.md). Blaze rods, ghast tears, breeze rods,
shulker shells and nether stars now drop from Pokemon through species
additions (self-test drop_additions_apply). The field guide counts vanilla
mobs as absent, applies species additions and reads the veins as sources.

Cobblebase tried (loads, self-tests pass) and left out until Adrian
decides its scope. Phase 4 checklist with the open questions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-30 03:36:50 +01:00
1 parent 5d275e4e14
commit 1a1fb93da8
33 files changed
+1279 -126

No files matched your search

+13 -3
View File
@@ -47,17 +47,17 @@ Creates or updates the Prism instance **Cobblemon Survival Pack (dev)** from `bu
```bash
python3 tools/quick_check.py
```
The everyday check after a change (about 1–2 minutes, one server boot): the smoke checks below, the in-game self-tests (next), `/locate` proof that ruined portals don't generate, and a sampled world (spawn plus a stronghold, mineshaft, trial chambers, ancient city, Gimmighoul towers and habitats) checked for ore, vanilla mobs and mob sources, unlisted biomes and gamerules, plus Lootr chests in a village.
The everyday check after a change (about 5 minutes, two server boots): the smoke checks below, the in-game self-tests (next), `/locate` proof that ruined portals don't generate, and a sampled world (spawn plus a stronghold, mineshaft, trial chambers, ancient city, Gimmighoul towers and habitats) checked for ore outside regenerating veins or outside their zone, vanilla mobs and mob sources, unlisted biomes and gamerules, plus Lootr chests in a village. It then starts the server a second time for the self-tests that span a restart.
```bash
python3 tools/selftest.py
```
Only the companion mod's in-game tests, on a fresh flat world (faster while working on them). They play real situations on the live server with every mod and config of the pack: for permadeath, Pokémon faint from a fall, lava, poison, in wild and trainer battles, with and without a Revival Charm, and in the PC. They use Minecraft's GameTest framework, started by `/cobblesurvival selftest run`; the command only exists when the server runs with `-Dcobblesurvival.selftest=true`. Tests live in `mod/src/main/kotlin/dev/cobblesurvival/selftest/`.
Only the companion mod's in-game tests, on a fresh flat world (faster while working on them), with a second server start for the tests that span a restart. They play real situations on the live server with every mod and config of the pack: for permadeath, Pokémon faint from a fall, lava, poison, in wild and trainer battles, with and without a Revival Charm, and in the PC. They use Minecraft's GameTest framework, started by `/cobblesurvival selftest run`; the command only exists when the server runs with `-Dcobblesurvival.selftest=true`. Tests live in `mod/src/main/kotlin/dev/cobblesurvival/selftest/`.
```bash
python3 tools/make_world.py
```
Builds the island world template (`build/world-template`, about 6 minutes), runs the same world checks on the whole island plus border fit and End access, and renders `build/island-map.png`. Only needed when the island itself should change. Details in [world/README.md](world/README.md). Run `tools/prism_instance.py` afterwards to put it in Prism as the save "Cobblemon Survival Island".
Builds the island world template (`build/world-template`, about 20 minutes: pregeneration, then a pass that waits until every chunk has its ore veins, then the showcase veins), runs the same world checks on the whole island plus border fit and End access, and renders `build/island-map.png`. Only needed when the island itself should change. Details in [world/README.md](world/README.md). Run `tools/prism_instance.py` afterwards to put it in Prism as the save "Cobblemon Survival Island".
```bash
python3 tools/zone_layout.py
@@ -69,6 +69,16 @@ python3 tools/zone_spawns.py
```
Writes each zone's spawn pool from Cobblemon's spawn data (every evolution line on the island gets one home zone; levels follow the zone's band) and its Alpha guardian, and lists both in `docs/zone-species.md`. Run after `tools/zone_layout.py` and the field guide; pin a line to a zone in `world/zones.json` → `species`.
```bash
python3 tools/zone_ores.py
```
Writes Regenerating Ore Veins' config (`pack/config/regenerating_ore_veins/`) from `world/zones.json` → `ores`: each ore tier's veins only in its zone, plus `world/vein-sources.json` for the field guide. Run after changing the ore tiers or the zone grid; the template must be rebuilt for new veins.
```bash
python3 tools/drop_audit.py
```
Checks that every item a Pokémon or a vanilla mob drops and a recipe or brewing consumes has a source on the island (only Pokémon live there), and writes `docs/pokemon-drops.md`. Uses the field guide's model and its last KubeJS export, no server.
```bash
python3 tools/fieldguide/build.py
```
@@ -0,0 +1,24 @@
{
"target": "cobblemon:carkol",
"drops": {
"amount": 5,
"entries": [
{
"item": "minecraft:coal",
"quantityRange": "0-2"
},
{
"item": "cobblemon:black_augurite",
"percentage": 5.0
},
{
"item": "cobblemon:passho_berry",
"percentage": 5.0
},
{
"item": "minecraft:blaze_rod",
"percentage": 10.0
}
]
}
}
@@ -0,0 +1,20 @@
{
"target": "cobblemon:charizard",
"drops": {
"amount": 5,
"entries": [
{
"item": "minecraft:blaze_powder",
"quantityRange": "0-3"
},
{
"item": "cobblemon:charcoal_stick",
"percentage": 25.0
},
{
"item": "minecraft:nether_star",
"percentage": 5.0
}
]
}
}
@@ -0,0 +1,20 @@
{
"target": "cobblemon:cloyster",
"drops": {
"amount": 3,
"entries": [
{
"item": "cobblemon:aspear_berry",
"percentage": 5.0
},
{
"item": "cobblemon:shell_bell",
"percentage": 5.0
},
{
"item": "minecraft:shulker_shell",
"percentage": 10.0
}
]
}
}
@@ -0,0 +1,24 @@
{
"target": "cobblemon:drifloon",
"drops": {
"amount": 4,
"entries": [
{
"item": "minecraft:phantom_membrane",
"percentage": 2.5
},
{
"item": "cobblemon:kasib_berry",
"percentage": 2.5
},
{
"item": "cobblemon:air_balloon",
"percentage": 2.5
},
{
"item": "minecraft:ghast_tear",
"percentage": 5.0
}
]
}
}
@@ -0,0 +1,24 @@
{
"target": "cobblemon:dusclops",
"drops": {
"amount": 4,
"entries": [
{
"item": "minecraft:phantom_membrane",
"percentage": 5.0
},
{
"item": "cobblemon:reaper_cloth",
"percentage": 5.0
},
{
"item": "cobblemon:kasib_berry",
"percentage": 5.0
},
{
"item": "minecraft:ghast_tear",
"percentage": 10.0
}
]
}
}
@@ -0,0 +1,19 @@
{
"target": "cobblemon:shuckle",
"drops": {
"amount": 3,
"entries": [
{
"item": "cobblemon:berry_juice"
},
{
"item": "cobblemon:luminous_moss",
"percentage": 5.0
},
{
"item": "minecraft:shulker_shell",
"percentage": 10.0
}
]
}
}
@@ -0,0 +1,29 @@
{
"target": "cobblemon:torkoal",
"drops": {
"amount": 6,
"entries": [
{
"item": "minecraft:coal",
"quantityRange": "0-2"
},
{
"item": "cobblemon:charcoal_stick",
"percentage": 5.0
},
{
"item": "cobblemon:smoke_ball",
"percentage": 5.0
},
{
"item": "cobblemon:charti_berry",
"percentage": 5.0
},
{
"item": "minecraft:blaze_rod",
"percentage": 25.0,
"quantityRange": "1-2"
}
]
}
}
@@ -0,0 +1,24 @@
{
"target": "cobblemon:whimsicott",
"drops": {
"amount": 5,
"entries": [
{
"item": "minecraft:white_wool",
"quantityRange": "1-2"
},
{
"item": "cobblemon:kebia_berry",
"percentage": 5.0
},
{
"item": "cobblemon:absorb_bulb",
"percentage": 5.0
},
{
"item": "minecraft:breeze_rod",
"percentage": 10.0
}
]
}
}
+1 -1
View File
@@ -52,7 +52,7 @@ JEI declares Minecraft `[1.21, 1.21.1)` in every 1.21.1 build, which a strict re
| Chunky | 1 (build tool only, not in the pack) | 1.4.23 (MR `LuFhm4eU`, CF project `485681`) | MR + CF | n/a. `tools/make_world.py` adds it to the test server only while pregenerating |
| Cold Sweat | 3 | 2.4.4 (MR `UGoodVYD`, CF `9215368`) | MR + CF | **In the pack** (2026-10-29); same jar on both platforms |
| Regenerating Ore Veins | 4 | 1.4.0 (CF `8066055`) | **CF only** | **In the pack** (2026-10-30); n/a (no Cobblemon dependency). Left out of the Modrinth export |
| Cobblebase | 4 | 2.0.1+1.8.0 (MR `pFYNQ6W2`) | MR has the 1.8 build; **CF only has 2.0.0+1.7.0** | ✅ 2.0.1 requires ≥ 1.8.0 and fixes a startup crash on 1.8. Modrinth lists Xaero's Minimap, Cobbreeding and Cloth Config as required, but the jar declares only Cobblemon and Kotlin for Forge; verify when adding |
| Cobblebase | 4 | 2.0.1+1.8.0 (MR `pFYNQ6W2`) | MR has the 1.8 build; **CF only has 2.0.0+1.7.0** | ✅ 2.0.1 requires ≥ 1.8.0 and fixes a startup crash on 1.8. Modrinth lists Xaero's Minimap, Cobbreeding and Cloth Config as required, but the jar declares only Cobblemon and Kotlin for Forge. **Tried 2026-10-30:** loads with the pack without Cobbreeding and Cloth Config, all self-tests pass; MPL-2.0. Left out until Adrian decides which skills to keep (`docs/checklists/phase-4.md`) |
| Cobblemon Poke Power | 4 (or own generator, Phase 6) | 1.3.1 (MR `vGpaTxmN`) | **MR only** | ✅ Declares `[1.8.0,)`. Needs Matthiesen Core |
| Cobblemon Quests (FTB Quests integration) | 8 | 1.2.0 (MR `8KeptEg2`; CF project `922979`) | MR + CF | ❌ Targets 1.7. Its own changelog says it does not work with FTB Quests ≥ 2101.1.19; the pack has 2101.1.37. Blocked until updated |
| Quests & Teams Fixes (flexible-mode soft-lock fix) | 8 | — | MR | ❌ Only 1.20.1 builds exist. Test the soft-lock on FTB Quests 2101.1.37 ourselves |
+7 -1
View File
@@ -30,6 +30,12 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue
| Level pressure | full experience up to 5 levels above the zone's band, then 10 % less per level, at least 10 % (Exp. Candy and commands exempt) | Decided (Adrian, 2026-10-30) | `world/zones.json` → `level_pressure` | E.g. on Button Isle (up to Lv 10): Lv 15 full, Lv 20 half, Lv 24+ a tenth |
| Strong flyer | ridable through the air with top speed ≥ 60 or top stamina ≥ 85 (Cobblemon ride stats) | Decided (Adrian, 2026-10-30) | `tools/zone_spawns.py` (`STRONG_FLYER_*`) | 29 species |
| High zone for strong flyers | band starts at Lv 30 or more (Sunscorch, Frostpeak, Deep Sea, Deep Dark, Basalt Furnace) | Decided (Adrian, 2026-10-30) | `tools/zone_spawns.py` (`HIGH_ZONE_LEVEL`) | |
| Ore tiers per zone | Button Isle: coal; Southwold: copper; Westmarch: iron, thunder stone; Verdant Jungle: redstone, leaf stone; Highland Meadows: lapis, sun stone; Sunscorch: gold, fire stone; Frostpeak Range: emerald, ice stone, dawn stone; Dripstone Depths: amethyst, moon stone; Deep Dark: diamond, dusk stone; Basalt Furnace: quartz, netherite; Lush Caves: shiny stone; Mangrove Mire: water stone | Placeholder | `world/zones.json` → `ores` → `tools/zone_ores.py` | Each tier in exactly one zone; evolution stones are tiers (their natural ores are off) |
| Vein regrowth | 20 min: coal; 30 min: copper; 40 min: iron; 45 min: redstone, lapis; 60 min: gold, quartz, thunder stone, shiny stone, leaf stone, water stone, moon stone, sun stone, fire stone, ice stone; 75 min: emerald, dawn stone, dusk stone; 90 min: diamond; 120 min: amethyst; 180 min: netherite; ±10 % jitter; real time | Placeholder | `world/zones.json` → `ores` (`regen_minutes`, `ore_defaults.jitter`) | Counts while the server is off too |
| Vein spacing, size, tries | spacing 4–14 chunks between candidate chunks, radius 0–2, 70 % filled, 1–4 tries per candidate chunk (per tier in `world/zones.json`) | Placeholder | `world/zones.json` → `ores`, `ore_defaults` | Ore blocks in the template (2026-10-30): copper 10,400, iron 6,356, quartz 2,397, lapis 2,236, coal 2,222, redstone 1,044, gold 815, diamond 559, shiny stone 466, thunder stone 239, sun stone 238, amethyst 238, dusk stone 222, emerald 181, leaf stone 125, ice stone 102, moon stone 100, fire stone 98, water stone 95, netherite 74, dawn stone 64. Per zone in `build/island-report.json` after `tools/make_world.py` |
| Regenerators breakable by players | no; explosions don't hurt veins | Placeholder | `tools/zone_ores.py` → `global.json` | Otherwise a player could remove a vein for good |
| Vein Locator | compass + copper ingot; 75 % chance to break per use (the mod's default) | Placeholder | `tools/zone_ores.py` → `vein_locator.json` | The mod's default recipe needs netherite |
| Drops for mobs the island lacks | Blaze Rod: Carkol 10 %, Torkoal 25 % ×1–2; Ghast Tear: Drifloon 5 %, Dusclops 10 %; Breeze Rod: Whimsicott 10 %; Shulker Shell: Shuckle 10 %, Cloyster 10 %; Nether Star: Charizard 5 % | Placeholder | `datapacks/core/data/cobblesurvival/species_additions/` | Every drop and what consumes it: `docs/pokemon-drops.md` (`tools/drop_audit.py`) |
| Ride stats (speed, stamina, ...) | Cobblemon's own | To tune after play-testing | species `riding` via `species_additions` | |
| Healing while sleeping | off (`healPercent` 0) | Decided (roadmap) | `config/cobblemon/main.json` | |
| Loot container refresh | 1 hour (72,000 ticks of game time) after first opened, all containers | Decided (Adrian, 2026-10-29) | `config/lootr-common.toml` | Tiering by structure/biome later |
@@ -39,4 +45,4 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue
| Server heap for smoke test | 4 GB | Tooling | `tools/smoke_test.py` | Not a gameplay value |
| Dev client heap (Prism) | 6 GB | Tooling | `tools/prism_instance.py --memory` | Not a gameplay value |
Sections to fill as phases land: zone level bands (Phase 3), drop rates and drop → consumer list (Phase 4), vein regeneration timers (Phase 4), pasture job cooldowns (Phase 4), hazard damage (Phase 3), field-move cooldowns and caps (Phase 5), machine output (Phase 6), boss attack damage and telegraph times (Phase 7).
Sections to fill as phases land: pasture job cooldowns (Phase 4), hazard damage (Phase 3), field-move cooldowns and caps (Phase 5), machine output (Phase 6), boss attack damage and telegraph times (Phase 7).
+25
View File
@@ -0,0 +1,25 @@
# Phase 4 – checks for Adrian
## Built so far
- **Ore veins** (Regenerating Ore Veins). Ore only comes from veins that grow back (and from chest loot). Each of the 21 ore tiers has veins in exactly one zone; Cobblemon's evolution stones are tiers too (`docs/balance.md` → "Ore tiers per zone"). Automated: the world report on the template (ore only in tracked veins inside their tier's zone, every tier present, every chunk filled) and the self-tests `vein_regrows_after_unload` and `vein_regrows_after_restart`.
- **Showcase veins.** One per surface zone sticks out of the ground near the zone's middle; on Button Isle at about −100, ~106, −92, a short walk from spawn.
- **Drops for mobs the island lacks.** Blaze rods, ghast tears, breeze rods, shulker shells and nether stars now drop from Pokémon; every drop and what consumes it is in `docs/pokemon-drops.md` (`tools/drop_audit.py` fails if a crafting input has no source). Automated: `drop_additions_apply`.
## In game (Prism instance)
The new template is the save folder "Cobblemon Survival Island (Phase 4)"; the world list shows it as "Cobblemon Survival Island" too, the newer of the two. The save you played on 28 Oct is untouched (veins only grow in new chunks, so it has almost no ore).
- [ ] Walk to the Button Isle showcase vein (about −100, ~106, −92), mine a coal block: it turns into a regenerator block, and right-clicking it says how long until it grows back (20 minutes of real time for coal).
- [ ] The regenerator can't be broken in survival (pickaxe or not), and TNT next to a vein leaves the vein alone.
- [ ] Craft a Vein Locator (compass + copper ingot) and use it underground in Westmarch: it should point at iron.
- [ ] Dig around under a zone: only that zone's ores show up (e.g. no iron under Southwold, only copper).
- [ ] JEI shows the Blaze Rod as a Carkol/Torkoal drop in Cobblemon's Pokédex drop list (or defeat one with `/pokespawn carkol` in creative).
## Ask Adrian: Phase 4 decisions
1. **Evolution stones as vein tiers.** Their natural ores have been off since Phase 1, so stones had no source at all. Now each stone has veins in one zone (Leaf Stone in the jungle, Water Stone in the Mire, Ice and Dawn Stone on Frostpeak, ...). Keep, move stones, or get them some other way?
2. **Cobblebase (pasture jobs).** 2.0.1+1.8.0 loads on Cobblemon 1.8 with the pack, and all self-tests still pass with it (tried 2026-10-30, then taken out again until you decide; Modrinth only, CurseForge has only the 1.7 build). Its config has a switch per skill group (healing, recruiting, passive XP, finders, buffs, ...). It's a whole Palworld-style job system with 47 skills, and several cut across the pack's rules: a Healer skill (healing friction), Excavator/Mining (ore outside the zone veins), Alchemist (evolution stones), Breeder/Egg Hatcher, Friend Recruiter (spawns new Pokémon at the base, outside the zones), passive XP (5 % a minute for pastured Pokémon). Modrinth lists Cobbreeding (breeding; license "MIT, no AI, no reupload") as required, though Cobblebase's jar doesn't need it. Options: (a) Cobblebase with only Producer and skills that don't bypass zones or healing, (b) Cobblebase as it comes, (c) skip it and do base production in the companion mod in Phase 6. And: breeding, yes or no?
3. **Power** (roadmap): Cobblemon Poke Power (Electric types output Forge Energy; Modrinth only, needs Matthiesen Core, already in the pack) or our own generator in Phase 6?
4. **Placeholders** in `docs/balance.md`: the ore tier table, vein regrowth times (real time), vein spacing and size, unbreakable regenerators, the Vein Locator recipe, and the drop picks (Carkol/Torkoal blaze rods, Drifloon/Dusclops ghast tears, Whimsicott breeze rods, Shuckle/Cloyster shulker shells, Charizard nether stars).
+16
View File
@@ -128,6 +128,22 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
- Cold Sweat's own animals (chameleons) can't join, like vanilla mobs: the only-Pokémon rule now lets in Cobblemon's entities only.
- Tested on the island itself (`cold_needs_fur`, `heat_needs_hide`, `lowlands_are_mild` in `tools/quick_check.py`): players stand at real spots in each zone, their body drift is turned into minutes until it hurts, and a frozen player without the grace period takes damage.
## Phase 4: resources (in progress, placeholders until Adrian approves)
**Ore veins.** Ore only comes from [Regenerating Ore Veins](https://www.curseforge.com/minecraft/mc-mods/regenerating-ore-veins) (plus chest loot): a mined vein block turns into a regenerator and grows back after its time, which counts in real time, unlike the guardians' game time. Each ore tier has veins in exactly one zone, higher tiers in higher zones (table in `docs/balance.md`). `tools/zone_ores.py` writes the mod's config (`pack/config/regenerating_ore_veins/`) from `world/zones.json` → `ores`:
- A surface zone is a set of boxes cut from the zone grid; the mod checks every block of a vein against them, so no vein block lies outside its zone. Cave biomes are zones of their own, so surface tiers stay out of them; the mod checks the biome only at a vein's centre, so a vein's edge can reach up to two blocks over a cave border. Cave tiers are limited to their cave biome and the depths where it lies (the Deep Dark mostly below y −24, the others between 0 and 40).
- Tiers with an ordinary and a deepslate ore get two veins: the ordinary ore from y 0 up, the deepslate one below.
- **Cobblemon's evolution stones are tiers too** (new in Phase 4, flagged): their natural ores have been off since Phase 1, so stones had no source. Each stone lives in one zone that fits it (Leaf Stone in the jungle, Water Stone in the Mire, Ice and Dawn Stone on Frostpeak, ...).
- Players can't break regenerators (`allow_breaking` false), so nobody removes a vein for good, and explosions don't hurt veins. The Vein Locator is crafted from a compass and a copper ingot instead of netherite.
- The mod fills a new chunk with veins only while the chunk is loaded, 8 chunks a tick, and forgets the rest when the server stops. Pregeneration is faster than that, so `tools/make_world.py` loads the island again row by row until every chunk is filled (`/cobblesurvival veins unfilled` counts what's left), and the world report fails on any unfilled chunk. On a live server new chunks fill as players load them.
- One showcase vein per surface zone (its first tier) sticks out of the ground near the zone's sample point, so players see what a vein looks like before they dig.
- Checked: the world report (ore only in tracked veins inside their tier's zone, every tier present, every chunk filled) and the self-tests `vein_regrows_after_unload` and `vein_regrows_after_restart` (a second server start in `tools/selftest.py` and `tools/quick_check.py`).
**Unique drops.** Only Pokémon live on the island, so a mob's drop needs another source. `tools/drop_audit.py` checks every item a Pokémon or a vanilla mob drops that a recipe or brewing consumes, and writes `docs/pokemon-drops.md` (item, wild Pokémon with zone and chance, other sources, consumers). Gaps it found, filled through Cobblemon species additions (`datapacks/core/data/cobblesurvival/species_additions/`, placeholders): Blaze Rod (Carkol in Westmarch, Torkoal in the Basalt Furnace; needed for brewing stands, blaze powder and Eyes of Ender), Ghast Tear (Drifloon, Dusclops), Breeze Rod (Whimsicott), Shulker Shell (Shuckle, Cloyster), Nether Star (Charizard). The tide armour trim and the wither skeleton skull stay without a source (cosmetic here). A zone spawn with its own drops overrides the species' drops, so the audit also fails if an addition targets such a spawn (Magmortar's and Centiskorch's did). Self-test: `drop_additions_apply`.
The field guide learned two things on the way: vanilla mobs count as absent (the companion mod lets only Cobblemon's entities join a world), and species additions replace the drops they set. The veins come in as sources from `world/vein-sources.json`.
## Open decisions for Adrian (proceeding with the default, flagged)
| Decision | Default used for now |
+2 -2
View File
@@ -31,7 +31,7 @@ The HTML works from disk (no server, no network) and follows the system's light
The data stack mirrors Minecraft's pack order: vanilla server data, NeoForge, every jar named in `pack/mods/*.pw.toml` (plus the companion mod), then `datapacks/core`, then `pack/kubejs` on top (KubeJS serves its `data/` as a data pack and its `assets/` as a resource pack; the guide reads textures and lang from there). A higher layer replaces a file, tags merge across layers, and a `pack.mcmeta` `filter` block hides the matching files of the layers below, so now that `datapacks/core` filters out Cobblemon's spawn pools and adds the zone pools, `spawns` and every page show only the zone pools. Cobblemon's own entries stay in `fieldguide.json` under `hidden_spawns`, in the same shape and resolved against the island the same way (status is what the entry would have if it were active), because `tools/zone_spawns.py` plans the zones from them; they count for nothing else. Jars are copied to `build/fieldguide-cache/jars/` first.
The island comes from `world/biomes.json` (`allowed` + `water`), the world preset named in `world/world.json` (which dimensions exist: overworld and the End, no Nether), structure and structure-set JSON (which structures can generate in the island's biomes), biome feature lists plus NeoForge biome modifiers (which blocks generate naturally, and which ores the pack switched off), and biome spawners plus structure spawn overrides (which vanilla mobs exist).
The island comes from `world/biomes.json` (`allowed` + `water`), the world preset named in `world/world.json` (which dimensions exist: overworld and the End, no Nether), structure and structure-set JSON (which structures can generate in the island's biomes), biome feature lists plus NeoForge biome modifiers (which blocks generate naturally, and which ores the pack switched off), and biome spawners plus structure spawn overrides (where vanilla mobs would spawn). The companion mod lets no mob but Cobblemon's join a world, apart from the entity tag `cobblesurvival:allowed_vanilla_mobs` (the Ender Dragon), so every other mob counts as absent and its drops need another source.
Spawns follow Cobblemon 1.8.4's rules: a spawn's conditions are alternatives, anticonditions veto, presets are merged into every condition (lists appended, single values kept), and a biome named in any anticondition never counts. A spawn that needs a structure is only listed in the biomes that structure generates in.
@@ -66,7 +66,7 @@ If the export cannot run (no EULA in `build/server/eula.txt`, a test server is a
## Adding sources: `--extra`
Sources the data cannot show yet (Phase 4 ore veins, trades, code-only mechanics) can be fed in without touching the code:
Sources the data cannot show yet (trades, code-only mechanics) can be fed in without touching the code. The Phase 4 ore veins come this way too: `tools/zone_ores.py` writes `world/vein-sources.json`, which the build always reads.
```json
{
+185
View File
@@ -0,0 +1,185 @@
# Pokémon drops and what they're for
Generated by `tools/drop_audit.py` (roadmap Phase 4, "unique drops"): every item a Pokémon or a vanilla mob drops that a recipe or brewing consumes. Only Pokémon live on the island, so a mob's drop needs another source. Zones are the wild Pokémon's home zones (`docs/zone-species.md`); chances are per defeat. Other sources are cut to five.
| Item | Wild Pokémon that drop it | Other sources | Consumed by |
| --- | --- | --- | --- |
| Acacia Log (`minecraft:acacia_log`) | – | Break Acacia Log | Acacia Planks, Acacia Wood, Campfire, Charcoal, Smoker, Soul Campfire |
| Amethyst Shard (`minecraft:amethyst_shard`) | Glimmet (jungle, ×0-1); Sableye (button_isle, ×0-2) | Break Amethyst Cluster; Loot in Ancient City; Regenerating amethyst vein in Dripstone Depths | Ability Shield, Blank TM, Block of Amethyst, Calibrated Sculk Sensor, Clear Amulet, Eviolite, Exp. Share, Fairy Feather … |
| Apple (`minecraft:apple`) | Appletun (mire, ×1); Applin (mire, ×1); Flapple (mire, ×1); Munchlax (jungle, ×0-3); Torterra (highlands, ×0-3) | Break Oak Leaves; Loot in Village Desert, Village Plains; Loot in Village Plains | Candied Apple, Golden Apple, Open-Faced Sandwich |
| Armadillo Scute (`minecraft:armadillo_scute`) | Sandshrew (sunscorch, ×0-1); Sandslash (sunscorch, ×0-2) | Use c:tools/brush on your Hakamo-o; Use c:tools/brush on your Jangmo-o; Use c:tools/brush on your Kommo-o; Use c:tools/brush on your Sandshrew; Use c:tools/brush on your Sandslash | Assault Vest, Protector, Wolf Armor |
| Arrow (`minecraft:arrow`) | – | Crafting; Loot in Decaying Crypt Ruins (cobblemon), Deserted Gimmi Tower (cobblemon), Deserted Monument Ruins (cobblemon), Deserted Tower Ruins (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon) and 10 more; Loot in Jungle Pyramid; Loot in Pillager Outpost; Loot in Trial Chambers | Spectral Arrow |
| Aspear Berry (`cobblemon:aspear_berry`) | Carvanha (shallows, 2.5%); Cloyster (deep_sea, 5%); Crabrawler (shallows, 2.5%); Cryogonal (frostpeak, 5%); Jynx (frostpeak, 5%); Lapras (deep_sea, 5%); Octillery (deep_sea, 5%); Remoraid (deep_sea, 2.5%); Shellder (deep_sea, 2.5%); Vanillish (frostpeak, 5%); Vanilluxe (frostpeak, 10%) | Break Aspear Berry; Wild berry trees in Cherry Grove, Jagged Peaks, Windswept Hills | Berry Juice, Candied Berries, Ice Heal, Yellow Dye |
| Babiri Berry (`cobblemon:babiri_berry`) | Carbink (westmarch, 5%); Clefable (dripstone, 10%); Clefairy (dripstone, 5%); Cleffa (dripstone, 2.5%); Froslass (frostpeak, 5%); Glalie (frostpeak, 5%); Lycanroc (frostpeak, 5%); Mime Jr. (westmarch, 2.5%); Patrat (southwold, 2.5%); Snubbull (southwold, 2.5%); Swirlix (southwold, 2.5%) | Break Babiri Berry; Wild berry trees in Cherry Grove, Jagged Peaks, Windswept Hills | Berry Juice, Candied Berries, Lime Dye |
| Bamboo (`minecraft:bamboo`) | Spinda (frostpeak, ×0-2) | Break Bamboo; Fishing; Fishing with a Poké Rod; Loot in Jungle Pyramid; Loot in Shipwreck, Shipwreck Beached | Block of Bamboo, Scaffolding, Stick |
| Basalt (`minecraft:basalt`) | – | Break Basalt | Polished Basalt, Smooth Basalt |
| Big Root (`cobblemon:big_root`) | Bellsprout (jungle, 2.5%); Carnivine (lush_caves, 5%); Diglett (button_isle, 2.5%); Lileep (lush_caves, 5%); Tangela (jungle, 2.5%); Tangrowth (jungle, 5%); Weepinbell (jungle, 5%) | Break Big Root; Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature) … | Remedy |
| Black Augurite (`cobblemon:black_augurite`) | Boldore (westmarch, 5%); Carkol (westmarch, 5%); Geodude (westmarch, 2.5%); Graveler (westmarch, 5%); Roggenrola (westmarch, 2.5%); Rolycoly (westmarch, 2.5%) | Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature); Brush suspicious blocks in Prehistoric Sandy Den (worldgen feature) | Obsidian, Stone Axe |
| Black Belt (`cobblemon:black_belt`) | Hariyama (frostpeak, 5%); Hitmonchan (frostpeak, 5%); Hitmonlee (frostpeak, 5%); Hitmontop (frostpeak, 5%); Meditite (button_isle, 2.5%); Sawk (frostpeak, 5%); Scrafty (sunscorch, 5%); Scraggy (sunscorch, 2.5%); Throh (frostpeak, 5%) | Crafting | Expert Belt |
| Black Sludge (`cobblemon:black_sludge`) | Croagunk (mire, 2.5%); Grimer (westmarch, 2.5%); Koffing (southwold, 2.5%); Toxicroak (mire, 5%); Trubbish (southwold, 2.5%); Varoom (westmarch, 2.5%) | – | Toxic Orb |
| Black Wool (`minecraft:black_wool`) | – | Break Black Wool; Crafting (shapeless) | Air Balloon, Black Banner, Black Bed, Black Carpet, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak … |
| Blaze Powder (`minecraft:blaze_powder`) | Braixen (sunscorch, ×0-2); Centiskorch (basalt, 10%); Charizard (basalt, ×0-3); Delphox (sunscorch, ×0-3); Fennekin (sunscorch, ×0-1); Heatmor (basalt, 10%); Houndoom (basalt, 10%); Larvesta (sunscorch, 2.5%); Magmortar (basalt, 25%); Ponyta (highlands, 2.5%) | Crafting (shapeless); Use c:tools/brush on your Volcarona | brewing: Strength; stand fuel, Expert Belt, Eye of Ender, Fire Charge, Flame Orb, Focus Band, Focus Sash, Magma Cream … |
| Blaze Rod (`minecraft:blaze_rod`) | Carkol (westmarch, 10%); Torkoal (basalt, 25%) | – | Blaze Powder, Brewing Stand, Choice Specs, Copper Bulb, End Rod, Exposed Copper Bulb, Oxidized Copper Bulb, Waxed Copper Bulb … |
| Blue Ice (`minecraft:blue_ice`) | – | Break Blue Ice; Crafting (shapeless) | Never-Melt Ice |
| Blue Wool (`minecraft:blue_wool`) | Herdier (westmarch, ×1-2); Lillipup (westmarch, ×1) | Break Blue Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Banner, Blue Bed, Blue Carpet, Brown Wool, Choice Scarf, Covert Cloak … |
| Bluk Berry (`cobblemon:bluk_berry`) | Drapion (sunscorch, 5%); Golisopod (jungle, 5%); Honchkrow (deep_dark, 5%); Illumise (mire, 5%); Indeedee (southwold, 5%); Purrloin (southwold, 2.5%); Sawk (frostpeak, 5%); Skorupi (sunscorch, 2.5%); Wimpod (jungle, 2.5%) | Break Bluk Berry; Wild berry trees in Cherry Grove, Jagged Peaks, Windswept Hills | Berry Juice, Candied Berries, Purple Dye |
| Bone (`minecraft:bone`) | Arcanine (mire, ×0-2); Boltund (westmarch, ×0-2); Cranidos (lush_caves, ×0-1); Cubone (sunscorch, ×0-1); Electrike (highlands, ×0-1); Furfrou (southwold, ×0-2); Growlithe (mire, ×0-1); Herdier (westmarch, ×0-2); Houndoom (basalt, ×0-2); Houndstone (deep_dark, ×1-3); Lillipup (westmarch, ×0-1); Lycanroc (frostpeak, ×0-2); Manectric (highlands, ×0-2); Marowak (sunscorch, ×1); Maschiff (westmarch, ×0-1); Mightyena (highlands, ×0-2); Shieldon (lush_caves, ×0-1); Snubbull (southwold, ×0-1); Yamper (westmarch, ×0-1) | Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature); Brush suspicious blocks in Prehistoric Hydrothermal Vents (worldgen feature) … | Bone Meal, Sharp Beak |
| Bone Block (`minecraft:bone_block`) | Wailmer (deep_sea, ×0-1); Wailord (deep_sea, ×0-2) | Break Bone Block; Crafting | Bone Meal |
| Bone Meal (`minecraft:bone_meal`) | Alomomola (shallows, 5%); Arrokuda (mire, 5%); Barraskewda (mire, 10%); Basculegion (frostpeak, 5%); Basculin (frostpeak, 5%); Bruxish (shallows, 5%); Dondozo (mire, 5%); Finneon (shallows, 5%); Goldeen (southwold, 5%); Gyarados (jungle, 10%); Kabuto (lush_caves, 5%); Magikarp (jungle, 5%); Milotic (deep_dark, 10%); Omanyte (lush_caves, 5%); Remoraid (deep_sea, 5%); Tatsugiri (mire, 5%); Veluza (deep_sea, 5%); Wishiwashi (shallows, 5%) | Break Composter; Crafting (shapeless); Loot in Trial Chambers | Bone Block, Cleanse Tag, Dire Hit, Growth Mulch, Guard Spec, Mulch, Terrain Extender, White Dye … |
| Bowl (`minecraft:bowl`) | – | Brush suspicious blocks in Deserted House Ruins (cobblemon); Brush suspicious blocks in Deserted Tower Ruins (cobblemon); Brush suspicious blocks in Deserted Town Center Ruins (cobblemon); Crafting; Fishing … | Beetroot Soup, Berry Juice, Leek and Potato Stew, Luminous Moss, Mushroom Stew, Rabbit Stew, Sinister Tea, Suspicious Stew … |
| Bread (`minecraft:bread`) | Fidough (southwold, ×0-1) | Crafting; Loot in Decaying Crypt Ruins (cobblemon), Mossy Oubliette Ruins (cobblemon), Unstable Cave Ruins (cobblemon); Loot in Mineshaft, Mineshaft Mesa; Loot in Monster Room (worldgen feature); Loot in Village Desert … | Open-Faced Sandwich, Vivichoke Dip |
| Breeze Rod (`minecraft:breeze_rod`) | Whimsicott (highlands, 10%) | – | brewing: Wind Charging, Mace, Smithing Template, Wind Charge |
| Bright Powder (`cobblemon:bright_powder`) | Beautifly (button_isle, 5%); Illumise (mire, 5%); Morelull (lush_caves, 2.5%); Scatterbug (button_isle, 2.5%); Shiinotic (lush_caves, 5%); Spewpa (button_isle, 2.5%); Volbeat (mire, 5%) | Break Bright Powder; Smelting | Glow Item Frame, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex |
| Brown Mushroom (`minecraft:brown_mushroom`) | Breloom (westmarch, ×0-2); Morelull (lush_caves, ×0-1); Shiinotic (lush_caves, ×0-2); Shroomish (westmarch, ×0-1) | Break Brown Mushroom; Break Brown Mushroom Block | Fermented Spider Eye, Mushroom Stew, Poké Bait, Rabbit Stew, Suspicious Stew |
| Brown Wool (`minecraft:brown_wool`) | Bouffalant (highlands, ×1-2) | Break Brown Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Banner, Brown Bed, Brown Carpet, Choice Scarf, Covert Cloak … |
| Cactus (`minecraft:cactus`) | Cacnea (sunscorch, ×0-1); Cacturne (sunscorch, ×0-2); Maractus (sunscorch, ×0-2) | Break Cactus; Break Potted Cactus; Loot in Village Desert; Use c:fertilizers on your Cacnea; Use c:fertilizers on your Cacturne | Green Dye |
| Candle (`minecraft:candle`) | – | Break Candle; Crafting; Loot in Ancient City | Black Candle, Blue Candle, Brown Candle, Cyan Candle, Gray Candle, Green Candle, Light Blue Candle, Light Gray Candle … |
| Carrot (`minecraft:carrot`) | Buneary (westmarch, 2.5%); Bunnelby (southwold, 2.5%) | Break Carrots; Loot in Pillager Outpost; Loot in Shipwreck, Shipwreck Beached | Carrot on a Stick, Golden Carrot, Rabbit Stew, Smoked-Tail Curry |
| Chameleon Molt (`cold_sweat:chameleon_molt`) | none (Cold Sweat's chameleon armour and Thermolith are not part of the pack's progression) | – | Chameleon Scale Boots, Chameleon Scale Chestplate, Chameleon Scale Helmet, Chameleon Scale Leggings, Thermolith |
| Charcoal (`minecraft:charcoal`) | Ninetales (highlands, 5%); Turtonator (basalt, 5%); Vulpix (highlands, 2.5%) | Break Campfire; Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Oak Tree (worldgen feature); Smelting | Campfire, Charcoal Stick, Fire Charge, Soul Torch, Torch |
| Charti Berry (`cobblemon:charti_berry`) | Centiskorch (basalt, 5%); Combee (button_isle, 2.5%); Delibird (frostpeak, 5%); Fearow (sunscorch, 5%); Frosmoth (frostpeak, 5%); Larvesta (sunscorch, 2.5%); Ledyba (button_isle, 2.5%); Taillow (southwold, 2.5%); Torkoal (basalt, 5%); Yanma (mire, 2.5%); Yanmega (mire, 5%) | Break Charti Berry; Wild berry trees in Badlands, Beach, Cherry Grove, Desert, Dripstone Caves, Jagged Peaks and 1 more | Berry Juice, Brown Dye, Candied Berries |
| Cheri Berry (`cobblemon:cheri_berry`) | Ampharos (highlands, 10%); Cherrim (frostpeak, 5%); Cutiefly (southwold, 2.5%); Dunsparce (westmarch, 2.5%); Electabuzz (frostpeak, 5%); Electivire (frostpeak, 10%); Electrike (highlands, 2.5%); Flaaffy (highlands, 5%); Glameow (southwold, 2.5%); Manectric (highlands, 5%); Mareep (highlands, 2.5%); Minun (southwold, 5%); Pachirisu (button_isle, 5%); Plusle (southwold, 5%); Scatterbug (button_isle, 2.5%); Spewpa (button_isle, 2.5%) | Break Cheri Berry; Wild berry trees in Plains | Berry Juice, Candied Berries, Paralyze Heal, Red Dye |
| Chesto Berry (`cobblemon:chesto_berry`) | Drowzee (southwold, 2.5%); Hippopotas (sunscorch, 2.5%); Hippowdon (sunscorch, 5%); Mimikyu (deep_dark, 5%); Minccino (southwold, 2.5%); Munchlax (jungle, 2.5%); Munna (southwold, 2.5%); Politoed (highlands, 10%); Poliwag (highlands, 2.5%); Poliwhirl (highlands, 5%); Poliwrath (highlands, 10%); Slakoth (jungle, 2.5%); Slowpoke (mire, 2.5%); Spinda (frostpeak, 5%); Vigoroth (jungle, 5%); Wailmer (deep_sea, 2.5%); Wailord (deep_sea, 5%); Whismur (southwold, 2.5%) | Break Chesto Berry; Wild berry trees in Cherry Grove, Forest | Awakening, Berry Juice, Blue Dye, Candied Berries |
| Chilan Berry (`cobblemon:chilan_berry`) | Bunnelby (southwold, 2.5%); Farfetch'd (westmarch, 5%); Herdier (westmarch, 5%); Hoothoot (button_isle, 2.5%); Lillipup (westmarch, 2.5%); Maushold (westmarch, 5%); Pidgeotto (highlands, 5%); Pidgey (highlands, 2.5%); Rattata (button_isle, 2.5%); Squawkabilly (southwold, 5%); Tandemaus (westmarch, 2.5%) | Break Chilan Berry; Wild berry trees in Cherry Grove, Forest, Plains | Berry Juice, Candied Berries, Yellow Dye |
| Chople Berry (`cobblemon:chople_berry`) | Buneary (westmarch, 2.5%); Lucario (frostpeak, 5%); Nosepass (westmarch, 2.5%); Pawniard (sunscorch, 2.5%); Pupitar (frostpeak, 5%); Sneasel (frostpeak, 2.5%); Tyranitar (frostpeak, 10%) | Break Chople Berry; Wild berry trees in Cherry Grove, Jagged Peaks, Windswept Hills | Berry Juice, Candied Berries, Red Dye |
| Clay Ball (`minecraft:clay_ball`) | Baltoy (westmarch, ×0-1); Barboach (southwold, ×0-1); Donphan (sunscorch, ×0-2); Golett (highlands, ×0-1); Marshtomp (mire, ×0-2); Mudbray (highlands, ×0-1); Mudkip (mire, ×0-1); Mudsdale (highlands, ×0-2); Palpitoad (sunscorch, ×0-2); Phanpy (sunscorch, ×0-1); Seismitoad (sunscorch, ×0-3); Shellos (shallows, ×0-1); Swampert (mire, ×0-3); Wooper (button_isle, ×0-1) | Break Clay; Loot in Village Desert | Brick, Chipped Pot, Clay, Cracked Pot, Light Clay, Masterpiece Teacup, Metal Coat, Unremarkable Teacup |
| Coal (`minecraft:coal`) | Carkol (westmarch, ×0-2); Rolycoly (westmarch, ×0-1); Torkoal (basalt, ×0-2) | Blast furnace; Break Coal Ore; Brush suspicious blocks in Ocean Ruin Cold; Brush suspicious blocks in Ocean Ruin Warm; Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature) … | Block of Coal, Campfire, Fire Charge, Soul Torch, Torch |
| Coba Berry (`cobblemon:coba_berry`) | Eldegoss (frostpeak, 5%); Hawlucha (westmarch, 5%); Heracross (westmarch, 5%); Kricketot (button_isle, 2.5%); Kricketune (button_isle, 5%); Leavanny (highlands, 10%); Lokix (highlands, 5%); Paras (lush_caves, 2.5%); Parasect (lush_caves, 5%); Sewaddle (highlands, 2.5%); Sunkern (button_isle, 2.5%); Swadloon (highlands, 5%) | Break Coba Berry; Wild berry trees in Cherry Grove, Forest, Jagged Peaks, Plains | Berry Juice, Candied Berries, Light Blue Dye |
| Colbur Berry (`cobblemon:colbur_berry`) | Baltoy (westmarch, 2.5%); Chingling (southwold, 2.5%); Elgyem (southwold, 2.5%); Espurr (southwold, 2.5%); Golett (highlands, 2.5%); Lunatone (dripstone, 5%); Sigilyph (southwold, 5%); Solrock (dripstone, 5%); Swoobat (jungle, 5%); Woobat (jungle, 2.5%); Wynaut (button_isle, 2.5%); Zorua (highlands, 2.5%) | Break Colbur Berry; Wild berry trees in Badlands, Deep Dark | Berry Juice, Candied Berries, Magenta Dye |
| Copper Ingot (`minecraft:copper_ingot`) | – | Blast furnace; Brush suspicious blocks in Decaying Crypt Ruins (cobblemon); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Rooted Gimmi Tower (cobblemon), Sunscorched Gimmi Tower (cobblemon), Temperate Gimmi Tower (cobblemon); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon), Rooted Gimmi Tower (cobblemon), Temperate Gimmi Tower (cobblemon) … | Ancient Azure Ball, Ancient Citrine Ball, Ancient Feather Ball, Ancient Heavy Ball, Ancient Ivory Ball, Ancient Poké Ball, Ancient Roseate Ball, Ancient Slate Ball … |
| Cyan Wool (`minecraft:cyan_wool`) | – | Break Cyan Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Banner, Cyan Bed … |
| Dandelion (`minecraft:dandelion`) | Skiploom (highlands, ×1) | Break Dandelion; Break Potted Dandelion; Loot in Village Plains; Use c:fertilizers on your Hoppip; Use c:fertilizers on your Jumpluff … | Suspicious Stew, Yellow Dye |
| Dawn Stone (`cobblemon:dawn_stone`) | Froslass (frostpeak, 5%); Glalie (frostpeak, 5%); Kirlia (westmarch, 5%); Ralts (westmarch, 2.5%) | Brush suspicious blocks in Frozen Gimmi Tower (cobblemon); Brush suspicious blocks in Lush Gimmi Tower (cobblemon); Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more … | Dawn Stone Block |
| Diamond (`minecraft:diamond`) | Carbink (westmarch, 5%); Sableye (button_isle, 5%) | Blast furnace; Break Deepslate Diamond Ore; Brush suspicious blocks in Deep Crypt (worldgen feature); Brush suspicious blocks in Desert Pyramid; Crafting (shapeless) … | Ability Shield, Beast Ball, Block of Diamond, Choice Scarf, Clear Amulet, Diamond Axe, Diamond Boots, Diamond Chestplate … |
| Diamond Sword (`minecraft:diamond_sword`) | – | Crafting; Loot in Trial Chambers | Netherite Sword |
| Dirt (`minecraft:dirt`) | Diglett (button_isle, ×0-1); Drilbur (westmarch, ×0-1) | Break Dirt; Break Farmland; Break Grass Block; Break Mycelium; Break Podzol | Coarse Dirt, Loamy Mulch, Mulch, Peat Block |
| Dragon's Breath (`minecraft:dragon_breath`) | Deino (mire, ×0-1); Dragonair (mire, ×0-2); Drampa (sunscorch, 5%); Dratini (mire, ×0-1) | – | brewing: lingering potions, Ability Capsule |
| Dusk Stone (`cobblemon:dusk_stone`) | Honedge (westmarch, 2.5%) | Brush suspicious blocks in Rooted Gimmi Tower (cobblemon); Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon) … | Dusk Stone Block |
| Echo Shard (`minecraft:echo_shard`) | – | Loot in Ancient City | Beast Ball, Recovery Compass |
| Egg (`minecraft:egg`) | Chansey (jungle, 50%); Exeggcute (jungle, ×0-3); Exeggutor (jungle, ×0-3) | Loot in Trial Chambers | Cake, Open-Faced Sandwich, Oran Lucky Egg, Pumpkin Pie |
| Electric Seed (`cobblemon:electric_seed`) | Togedemaru (frostpeak, 5%) | Break Electric Seed | Miracle Seed |
| Emerald (`minecraft:emerald`) | Nickit (westmarch, 2.5%); Sableye (button_isle, 5%); Thievul (westmarch, 5%) | Blast furnace; Break Emerald Ore; Brush suspicious blocks in Decaying Crypt Ruins (cobblemon); Brush suspicious blocks in Desert Pyramid; Brush suspicious blocks in Desert Well (worldgen feature) … | Block of Emerald |
| Ender Pearl (`minecraft:ender_pearl`) | Abra (highlands, ×0-1); Alakazam (highlands, ×0-3); Beldum (dripstone, ×0-1); Elgyem (southwold, ×0-1); Grumpig (frostpeak, ×0-2); Kadabra (highlands, ×0-2); Kirlia (westmarch, ×0-2); Metang (dripstone, ×0-2); Rabsca (sunscorch, ×1); Ralts (westmarch, ×0-1); Sigilyph (southwold, ×0-1); Unown (jungle, ×0-1) | Loot in Trial Chambers | Eye of Ender, Flame Orb, Life Orb, Light Ball, Light Clay, Link Cable, Smoke Ball, Toxic Orb |
| Everstone (`cobblemon:everstone`) | Boldore (westmarch, 5%); Geodude (westmarch, 2.5%); Graveler (westmarch, 5%); Roggenrola (westmarch, 2.5%) | Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature); Brush suspicious blocks in Prehistoric Hydrothermal Vents (worldgen feature) … | Eviolite |
| Feather (`minecraft:feather`) | Archen (lush_caves, ×0-2); Braviary (frostpeak, ×0-2); Chatot (jungle, ×0-2); Combusken (highlands, ×0-2); Corviknight (deep_dark, ×0-3); Cramorant (shallows, ×0-2); Dartrix (frostpeak, ×0-2); Decidueye (frostpeak, ×0-3); Delibird (frostpeak, ×0-2); Ducklett (mire, ×0-1); Farfetch'd (westmarch, ×0-1); Fearow (sunscorch, ×0-2); Flamigo (mire, ×0-2); Fletchinder (westmarch, ×0-2); Fletchling (westmarch, ×0-1); Golduck (highlands, ×0-2); Honchkrow (deep_dark, ×0-3); Hoothoot (button_isle, ×0-1); Kilowattrel (deep_sea, ×0-2); Natu (jungle, ×0-1); Pidgeotto (highlands, ×0-2); Pidgey (highlands, ×0-1); Pidove (southwold, ×0-1); Pikipek (jungle, ×0-1); Psyduck (highlands, ×0-1); Squawkabilly (southwold, ×0-2); Staraptor (frostpeak, ×0-3); Swanna (mire, ×0-2); Taillow (southwold, ×0-1); Torchic (highlands, ×0-1); Toucannon (jungle, ×0-3); Trumbeak (jungle, ×0-2); Wingull (shallows, ×0-1); Xatu (jungle, ×0-2) | Loot in Shipwreck, Shipwreck Beached; Loot in Village Plains; Use c:tools/brush on your Archen; Use c:tools/brush on your Archeops; Use c:tools/brush on your Blaziken … | Arrow, Blunder Policy, Book and Quill, Brush, Clever Feather, Fairy Feather, Genius Feather, Health Feather … |
| Fire Stone (`cobblemon:fire_stone`) | Pansear (jungle, 2.5%); Simisear (jungle, 5%) | Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon); Loot in Deep Crypt (worldgen feature), Lush Gimmi Tower (cobblemon) … | Fire Stone Block, Flame Orb, Heat Rock |
| Flint (`minecraft:flint`) | Nosepass (westmarch, ×0-1) | Break Gravel | Arrow, Fletching Table, Flint and Steel, Utility Umbrella |
| Ghast Tear (`minecraft:ghast_tear`) | Drifloon (westmarch, 5%); Dusclops (deep_dark, 10%) | – | brewing: Regeneration, Destiny Knot, End Crystal, Focus Sash, Life Orb, Reaper Cloth |
| Glass Bottle (`minecraft:glass_bottle`) | – | Crafting; Loot in Beach (cobblemon), Deep Ocean (cobblemon), Warm Ocean (cobblemon); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon) … | Antidote, Awakening, Burn Heal, Dire Hit, Full Heal, Guard Spec, Honey Bottle, Ice Heal … |
| Glow Ink Sac (`minecraft:glow_ink_sac`) | Frillish (deep_sea, ×0-1); Jellicent (deep_sea, ×0-2); Tentacool (westmarch, 10%) | – | Glow Item Frame, Light Clay, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex … |
| Glowstone Dust (`minecraft:glowstone_dust`) | – | Break Glowstone | brewing: stronger potions, Blunder Policy, Glowstone, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex … |
| Goat Fur (`cold_sweat:goat_fur`) | – | Crafting (pack recipe) | Goat Fur Boots, Goat Fur Cap, Goat Fur Pants, Goat Fur Parka, Minecart Insulation, Minecart with Insulation |
| Gold Ingot (`minecraft:gold_ingot`) | – | Blast furnace; Brush suspicious blocks in Decaying Crypt Ruins (cobblemon); Brush suspicious blocks in Deep Crypt (worldgen feature); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Rooted Gimmi Tower (cobblemon), Sunscorched Gimmi Tower (cobblemon), Temperate Gimmi Tower (cobblemon) … | Ancient Gigaton Ball, Ancient Jet Ball, Ancient Ultra Ball, Beast Ball, Black Gilded Chest, Block of Gold, Blue Gilded Chest, Chipped Pot … |
| Gold Nugget (`minecraft:gold_nugget`) | Meowth (southwold, ×0-1) | Blast furnace; Brush suspicious blocks in Ocean Ruin Cold; Brush suspicious blocks in Ocean Ruin Warm; Brush suspicious blocks in Trail Ruins; Crafting (shapeless) … | Chipped Pot, Cracked Pot, Eject Button, Glistering Melon Slice, Gold Ingot, Golden Carrot, Soulspring Lamp |
| Golden Helmet (`minecraft:golden_helmet`) | Falinks (sunscorch, 5%) | Crafting; Loot in Ocean Ruin Cold, Ocean Ruin Warm | Gold Nugget, Rocky Helmet |
| Grassy Seed (`cobblemon:grassy_seed`) | Bounsweet (jungle, 2.5%); Maractus (sunscorch, 5%); Steenee (jungle, 5%); Tsareena (jungle, 10%) | Break Grassy Seed | Miracle Seed |
| Gravel (`minecraft:gravel`) | Geodude (westmarch, ×0-1); Graveler (westmarch, ×0-2) | Break Gravel | Black Concrete Powder, Blue Concrete Powder, Brown Concrete Powder, Coarse Dirt, Cyan Concrete Powder, Gray Concrete Powder, Green Concrete Powder, Light Blue Concrete Powder … |
| Gray Wool (`minecraft:gray_wool`) | – | Break Gray Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Green Wool (`minecraft:green_wool`) | – | Break Green Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Gunpowder (`minecraft:gunpowder`) | Voltorb (southwold, ×0-1) | Brush suspicious blocks in Desert Pyramid; Loot in Desert Pyramid; Loot in Monster Room (worldgen feature); Loot in Shipwreck, Shipwreck Beached | brewing: splash potions, Fire Charge, Firework Rocket, TNT, Weakness Policy |
| Haban Berry (`cobblemon:haban_berry`) | Cyclizar (highlands, 5%); Drakloak (deep_sea, 5%); Druddigon (southwold, 5%); Fraxure (frostpeak, 5%); Gabite (mire, 5%); Gible (mire, 2.5%); Goomy (mire, 2.5%); Haxorus (frostpeak, 10%); Tatsugiri (mire, 5%); Turtonator (basalt, 5%) | Break Haban Berry; Wild berry trees in Cherry Grove, Jagged Peaks, Jungle, Windswept Hills | Berry Juice, Candied Berries, Red Dye |
| Hard Stone (`cobblemon:hard_stone`) | Boldore (westmarch, 5%); Bonsly (button_isle, 2.5%); Crustle (sunscorch, 5%); Dwebble (sunscorch, 2.5%); Lycanroc (frostpeak, 5%); Nosepass (westmarch, 2.5%); Onix (westmarch, 2.5%); Pupitar (frostpeak, 5%); Roggenrola (westmarch, 2.5%); Tyranitar (frostpeak, 10%) | Crafting | Damp Rock, Heat Rock, Icy Rock, Rocky Helmet, Smooth Rock |
| Heart of the Sea (`minecraft:heart_of_the_sea`) | Lapras (deep_sea, 5%) | Loot in Buried Treasure | Conduit, Soulspring Lamp |
| Honey Bottle (`minecraft:honey_bottle`) | Combee (button_isle, ×0-1); Cutiefly (southwold, ×0-1); Gloom (highlands, ×0-2); Surskit (mire, ×0-1); Teddiursa (mire, 2.5%); Ursaring (mire, 5%) | Crafting (shapeless); Loot in Trial Chambers; Use a glass bottle on a full bee nest; Use minecraft:glass_bottle on your Vespiquen | Berry Sweet, Clever Mochi, Clover Sweet, Flower Sweet, Fresh-Start Mochi, Genius Mochi, Health Mochi, Honey Block … |
| Honeycomb (`minecraft:honeycomb`) | Combee (button_isle, ×0-1) | Loot in Trial Chambers; Shear a full bee nest | Beehive, Candle, Courage Candy, Exp. Candy XS, Health Candy, Honeycomb Block, Metal Coat, Mighty Candy … |
| Ice Stone (`cobblemon:ice_stone`) | – | Brush suspicious blocks in Prehistoric Powdered Deposit (worldgen feature); Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon) … | Ice Stone Block, Icy Rock |
| Ink Sac (`minecraft:ink_sac`) | Clobbopus (shallows, ×1-3); Horsea (deep_sea, ×0-1); Inkay (shallows, ×0-1); Kingdra (deep_sea, ×0-3); Octillery (deep_sea, ×1-3); Seadra (deep_sea, ×0-2); Tentacool (westmarch, ×1-3) | Fishing; Fishing with a Poké Rod | Black Dye, Blunder Policy, Book and Quill, Spell Tag, Weakness Policy |
| Iron Ball (`cobblemon:iron_ball`) | Mawile (button_isle, 5%) | Break Iron Ball; Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon); Loot in Deep Crypt (worldgen feature), Lush Gimmi Tower (cobblemon) … | Loaded Dice |
| Iron Helmet (`minecraft:iron_helmet`) | Escavalier (mire, 5%); Pawniard (sunscorch, 2.5%); Shelmet (mire, 2.5%) | Crafting; Loot in Trial Chambers; Loot in Village Desert, Village Plains | Exp. Share, Iron Nugget |
| Iron Ingot (`minecraft:iron_ingot`) | Duraludon (frostpeak, ×0-1) | Blast furnace; Break Healing Machine; Break PC; Brush suspicious blocks in Decaying Crypt Ruins (cobblemon); Brush suspicious blocks in Deep Crypt (worldgen feature) … | Ability Shield, Activator Rail, Ancient Great Ball, Ancient Leaden Ball, Ancient Wing Ball, Anvil, Black Glasses, Black Plaque … |
| Iron Nugget (`minecraft:iron_nugget`) | Honedge (westmarch, ×0-1); Orthworm (southwold, ×0-2); Varoom (westmarch, ×0-1) | Blast furnace; Crafting (shapeless); Loot in Shipwreck, Shipwreck Beached; Smelting | Chain, Disc Shelf, Iron Ingot, Lantern, Metronome, Silver Powder, Soothe Bell, Soul Lantern … |
| Iron Sword (`minecraft:iron_sword`) | Honedge (westmarch, 2.5%) | Crafting; Loot in Buried Treasure; Loot in Trial Chambers; Loot in Village Desert, Village Plains | Iron Nugget |
| Kasib Berry (`cobblemon:kasib_berry`) | Abra (highlands, 2.5%); Alakazam (highlands, 10%); Brambleghast (sunscorch, 5%); Drifloon (westmarch, 2.5%); Dusclops (deep_dark, 5%); Dusknoir (deep_dark, 10%); Frillish (deep_sea, 2.5%); Houndstone (deep_dark, 5%); Jellicent (deep_sea, 5%); Kadabra (highlands, 5%); Kirlia (westmarch, 5%); Misdreavus (mire, 2.5%); Pumpkaboo (westmarch, 2.5%); Ralts (westmarch, 2.5%) | Break Kasib Berry; Wild berry trees in Deep Dark, Dripstone Caves, Lush Caves, Mangrove Swamp | Berry Juice, Candied Berries, Purple Dye |
| Kebia Berry (`cobblemon:kebia_berry`) | Aromatisse (frostpeak, 5%); Azumarill (southwold, 10%); Azurill (southwold, 2.5%); Breloom (westmarch, 5%); Carnivine (lush_caves, 5%); Comfey (southwold, 5%); Cottonee (highlands, 2.5%); Flabébé (mire, 2.5%); Floette (mire, 5%); Florges (mire, 10%); Lombre (southwold, 5%); Lotad (southwold, 2.5%); Marill (southwold, 5%); Morelull (lush_caves, 2.5%); Shiinotic (lush_caves, 5%); Shroomish (westmarch, 2.5%); Whimsicott (highlands, 5%) | Break Kebia Berry; Wild berry trees in Cherry Grove, Deep Dark, Forest, Mangrove Swamp | Berry Juice, Candied Berries, Green Dye |
| Kelp (`minecraft:kelp`) | Dhelmise (deep_sea, ×0-2); Dragalge (deep_sea, ×0-2); Skrelp (deep_sea, ×0-1) | Break Kelp; Break Kelp Plant; Use c:fertilizers on your Dhelmise | Dried Kelp |
| Leaf Stone (`cobblemon:leaf_stone`) | Pansage (jungle, 2.5%); Simisage (jungle, 5%) | Blast furnace; Break Leaf Stone Ore; Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Lush Den (worldgen feature); Brush suspicious blocks in Prehistoric Mossy Pond (worldgen feature) … | Leaf Stone Block |
| Leather (`minecraft:leather`) | Bouffalant (highlands, ×0-2); Deerling (westmarch, ×0-1); Miltank (highlands, ×0-2); Mudbray (highlands, ×0-1); Mudsdale (highlands, ×0-2); Ponyta (highlands, ×0-1); Tauros (highlands, ×0-2) | Crafting; Crafting (shapeless); Fishing; Fishing with a Poké Rod; Loot in Village Plains | Book, Eject Pack, Focus Band, Focus Sash, Hoglin Hide, Item Frame, Leather Boots, Leather Cap … |
| Light Blue Wool (`minecraft:light_blue_wool`) | Swoobat (jungle, ×1-2); Woobat (jungle, ×1) | Break Light Blue Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Light Gray Wool (`minecraft:light_gray_wool`) | – | Break Light Gray Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Lime Wool (`minecraft:lime_wool`) | – | Break Lime Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Magenta Wool (`minecraft:magenta_wool`) | – | Break Magenta Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Magma Cream (`minecraft:magma_cream`) | Camerupt (sunscorch, 5%); Numel (sunscorch, 2.5%); Slugma (southwold, ×0-1) | Crafting (shapeless) | brewing: Fire Resistance, Lava Cookie, Magma Block |
| Medicinal Leek (`cobblemon:medicinal_leek`) | Farfetch'd (westmarch, ×0-1) | Break Medicinal Leek | Leek and Potato Stew, Magenta Dye, Medicinal Brew, Open-Faced Sandwich, Roasted Leek |
| Melon Seeds (`minecraft:melon_seeds`) | Bulbasaur (jungle, ×0-1); Ivysaur (jungle, ×0-2) | Break Melon Stem; Crafting (shapeless); Loot in Mineshaft, Mineshaft Mesa; Loot in Monster Room (worldgen feature) | Miracle Seed |
| Misty Seed (`cobblemon:misty_seed`) | Comfey (southwold, 5%) | Break Misty Seed | Miracle Seed |
| Moon Stone (`cobblemon:moon_stone`) | Clefable (dripstone, 10%); Clefairy (dripstone, 5%); Cleffa (dripstone, 2.5%); Jigglypuff (highlands, 5%); Lunatone (dripstone, 5%); Wigglytuff (highlands, 10%) | Blast furnace; Break Deepslate Moon Stone Ore; Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more … | Moon Stone Block |
| Mud (`minecraft:mud`) | Stunfisk (jungle, ×0-2) | Break Mud; Use a water bottle on dirt | Humid Mulch, Muddy Mangrove Roots, Packed Mud, Peat Block |
| Muscle Band (`cobblemon:muscle_band`) | Annihilape (frostpeak, 10%); Gurdurr (westmarch, 5%); Machamp (frostpeak, 10%); Machoke (frostpeak, 5%); Primeape (frostpeak, 5%); Timburr (westmarch, 2.5%) | Crafting | Choice Band |
| Nanab Berry (`cobblemon:nanab_berry`) | Aipom (jungle, 2.5%); Copperajah (frostpeak, 5%); Cubone (sunscorch, 2.5%); Falinks (sunscorch, 5%); Fidough (southwold, 2.5%); Grafaiai (jungle, 5%); Joltik (southwold, 2.5%); Marowak (sunscorch, 5%); Meditite (button_isle, 2.5%); Shroodle (jungle, 2.5%); Tropius (jungle, ×0-2) | Break Nanab Berry; Wild berry trees in Jungle, Mangrove Swamp | Berry Juice, Candied Berries, Pink Dye |
| Nautilus Shell (`minecraft:nautilus_shell`) | Omanyte (lush_caves, ×1) | Fishing; Fishing with a Poké Rod | Conduit, Shell Bell |
| Nether Star (`minecraft:nether_star`) | Charizard (basalt, 5%) | – | Beacon, Master Ball |
| Occa Berry (`cobblemon:occa_berry`) | Abomasnow (frostpeak, 5%); Bronzor (westmarch, 2.5%); Burmy (southwold, 2.5%); Durant (basalt, 2.5%); Escavalier (mire, 5%); Ferroseed (lush_caves, 2.5%); Karrablast (mire, 2.5%); Mawile (button_isle, 5%); Pansage (jungle, 2.5%); Simisage (jungle, 5%) | Break Occa Berry; Wild berry trees in Badlands, Beach, Desert, Jungle | Berry Juice, Candied Berries, Orange Dye |
| Oran Berry (`cobblemon:oran_berry`) | Audino (southwold, 5%); Bidoof (button_isle, 2.5%); Furret (southwold, 5%); Gogoat (frostpeak, 5%); Greedent (westmarch, ×0-2); Jigglypuff (highlands, 5%); Lechonk (highlands, 2.5%); Lickilicky (highlands, 5%); Lickitung (highlands, 2.5%); Miltank (highlands, 5%); Oinkologne (highlands, 5%); Pichu (westmarch, 2.5%); Pikachu (westmarch, 5%); Sentret (southwold, 2.5%); Skwovet (westmarch, ×0-1); Teddiursa (mire, 2.5%); Ursaring (mire, 5%); Wigglytuff (highlands, 10%); Zigzagoon (southwold, 2.5%) | Break Oran Berry; Loot in Village Desert, Village Plains; Wild berry trees in Badlands, Beach, Cherry Grove, Deep Dark, Deep Lukewarm Ocean, Deep Ocean and 13 more | Berry Juice, Candied Berries, Light Blue Dye, Oran Lucky Egg, Potion |
| Orange Wool (`minecraft:orange_wool`) | – | Break Orange Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Passho Berry (`cobblemon:passho_berry`) | Bonsly (button_isle, 2.5%); Carkol (westmarch, 5%); Donphan (sunscorch, 5%); Garganacl (sunscorch, 10%); Mudbray (highlands, 2.5%); Mudsdale (highlands, 5%); Naclstack (sunscorch, 5%); Onix (westmarch, 2.5%); Pansear (jungle, 2.5%); Phanpy (sunscorch, 2.5%); Rhydon (frostpeak, 5%); Rhyperior (frostpeak, 10%); Rolycoly (westmarch, 2.5%); Sandygast (shallows, 2.5%); Simisear (jungle, 5%); Slugma (southwold, 2.5%); Stunfisk (jungle, 5%) | Break Passho Berry; Wild berry trees in Beach, Deep Lukewarm Ocean, Deep Ocean, Lukewarm Ocean, Mangrove Swamp, Ocean and 2 more | Berry Juice, Blue Dye, Candied Berries |
| Payapa Berry (`cobblemon:payapa_berry`) | Annihilape (frostpeak, 10%); Croagunk (mire, 2.5%); Flamigo (mire, 5%); Gastly (westmarch, 2.5%); Hariyama (frostpeak, 5%); Haunter (westmarch, 5%); Hitmonchan (frostpeak, 5%); Hitmonlee (frostpeak, 5%); Hitmontop (frostpeak, 5%); Mienshao (frostpeak, 5%); Primeape (frostpeak, 5%); Sneasler (frostpeak, 5%); Toxicroak (mire, 5%) | Break Payapa Berry; Wild berry trees in Cherry Grove, Deep Dark, Desert | Berry Juice, Candied Berries, Magenta Dye |
| Pecha Berry (`cobblemon:pecha_berry`) | Beautifly (button_isle, 5%); Bellossom (highlands, 10%); Cascoon (button_isle, 2.5%); Dragalge (deep_sea, 5%); Dustox (button_isle, 5%); Gloom (highlands, 5%); Mareanie (shallows, 2.5%); Mightyena (highlands, 5%); Oddish (highlands, 2.5%); Roselia (frostpeak, 5%); Roserade (frostpeak, 10%); Silcoon (button_isle, 2.5%); Skitty (button_isle, 2.5%); Skrelp (deep_sea, 2.5%); Stunky (westmarch, 2.5%); Trubbish (southwold, 2.5%); Venipede (lush_caves, 2.5%); Vileplume (highlands, 10%); Whirlipede (lush_caves, 5%); Wurmple (button_isle, 2.5%); Yungoos (southwold, 2.5%); Zangoose (highlands, 5%) | Break Pecha Berry; Wild berry trees in Jungle, Mangrove Swamp | Antidote, Berry Juice, Candied Berries, Pink Dye |
| Persim Berry (`cobblemon:persim_berry`) | Bounsweet (jungle, 2.5%); Chatot (jungle, 5%); Chinchou (shallows, 2.5%); Drampa (sunscorch, 5%); Golbat (jungle, 5%); Kecleon (jungle, 5%); Lilligant (westmarch, 5%); Natu (jungle, 2.5%); Palpitoad (sunscorch, 5%); Petilil (westmarch, 2.5%); Seismitoad (sunscorch, 10%); Seviper (highlands, 5%); Solosis (southwold, 2.5%); Steenee (jungle, 5%); Tsareena (jungle, 10%); Venonat (southwold, 2.5%); Xatu (jungle, 5%); Zubat (jungle, 2.5%) | Break Persim Berry; Wild berry trees in Badlands, Beach, Cherry Grove, Deep Dark, Deep Lukewarm Ocean, Deep Ocean and 13 more | Berry Juice, Candied Berries, Pink Dye |
| Phantom Membrane (`minecraft:phantom_membrane`) | Drakloak (deep_sea, 5%); Drifloon (westmarch, 2.5%); Dusclops (deep_dark, 5%); Dusknoir (deep_dark, 10%); Gliscor (basalt, 5%); Golbat (jungle, 5%); Misdreavus (mire, 2.5%); Noibat (jungle, 2.5%); Shuppet (southwold, 2.5%); Zubat (jungle, 2.5%) | Use c:tools/brush on your Dragapult; Use c:tools/brush on your Drakloak | brewing: Slow Falling, Air Balloon, Covert Cloak, Reaper Cloth, Smoke Ball |
| Pinap Berry (`cobblemon:pinap_berry`) | Beedrill (button_isle, 5%); Bellsprout (jungle, 2.5%); Clobbopus (shallows, 2.5%); Drilbur (westmarch, 2.5%); Kakuna (button_isle, 2.5%); Klawf (sunscorch, 5%); Krabby (shallows, 2.5%); Meowth (southwold, 2.5%); Pinsir (westmarch, 5%); Skarmory (sunscorch, 5%); Weedle (button_isle, 2.5%); Weepinbell (jungle, 5%) | Break Pinap Berry; Wild berry trees in Badlands, Desert | Berry Juice, Candied Berries, Yellow Dye |
| Pink Wool (`minecraft:pink_wool`) | – | Break Pink Wool; Crafting (shapeless); Use c:tools/brush on your Wigglytuff | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Poppy (`minecraft:poppy`) | Flabébé (mire, ×1); Floette (mire, ×1); Florges (mire, ×0-3) | Break Poppy; Loot in Village Plains | Red Dye, Suspicious Stew |
| Potato (`minecraft:potato`) | Diglett (button_isle, 2.5%) | Break Potatoes; Loot in Pillager Outpost; Loot in Shipwreck, Shipwreck Beached; Loot in Village Plains | Baked Potato, Old Gateau, Potato Mochi |
| Prismarine Crystals (`minecraft:prismarine_crystals`) | Chinchou (shallows, ×0-1) | Break Sea Lantern; Loot in Buried Treasure | Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Pokédex, Sea Lantern … |
| Prismarine Shard (`minecraft:prismarine_shard`) | Horsea (deep_sea, ×0-1); Kingdra (deep_sea, ×0-3); Qwilfish (shallows, ×0-1); Seadra (deep_sea, ×0-2) | – | Dark Prismarine, Prismarine, Prismarine Bricks, Sea Lantern, Smithing Template |
| Protector (`cobblemon:protector`) | Donphan (sunscorch, 5%); Rhydon (frostpeak, 5%); Rhyperior (frostpeak, 10%) | Brush suspicious blocks in Deserted Town Center Ruins (cobblemon); Brush suspicious blocks in Fallen Statue Ruins (cobblemon); Brush suspicious blocks in Mossy Oubliette Ruins (cobblemon); Brush suspicious blocks in Sunscorched Gimmi Tower (cobblemon); Crafting … | Assault Vest |
| Psychic Seed (`cobblemon:psychic_seed`) | Exeggcute (jungle, 2.5%); Exeggutor (jungle, 5%) | Break Psychic Seed | Miracle Seed |
| Pufferfish (`minecraft:pufferfish`) | Qwilfish (shallows, ×1) | Fishing | brewing: Water Breathing |
| Pumpkin Seeds (`minecraft:pumpkin_seeds`) | Pumpkaboo (westmarch, ×0-1) | Craft from a pumpkin; Crafting (shapeless); Loot in Mineshaft, Mineshaft Mesa; Loot in Monster Room (worldgen feature) | Miracle Seed, Pewter Crunchies |
| Purple Wool (`minecraft:purple_wool`) | – | Break Purple Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Rabbit Hide (`minecraft:rabbit_hide`) | Buneary (westmarch, ×0-1); Bunnelby (southwold, ×0-1); Cinderace (highlands, ×0-3); Raboot (highlands, ×0-2); Scorbunny (highlands, ×0-1) | – | Leather, Protective Pads, Punching Glove, Sachet, Soft Sand, Terrain Extender |
| Rabbit's Foot (`minecraft:rabbit_foot`) | Buneary (westmarch, 2.5%); Bunnelby (southwold, 2.5%); Cinderace (highlands, 25%); Raboot (highlands, 10%); Scorbunny (highlands, 5%) | – | brewing: Leaping, Blunder Policy, Loaded Dice |
| Raw Beef (`minecraft:beef`) | Bouffalant (highlands, ×1-3); Miltank (highlands, ×1-3); Tauros (highlands, ×1-3) | – | Open-Faced Sandwich, Steak |
| Raw Chicken (`minecraft:chicken`) | Braviary (frostpeak, ×1); Chatot (jungle, ×1); Combusken (highlands, ×1); Corviknight (deep_dark, ×1); Cramorant (shallows, ×1); Dartrix (frostpeak, ×1); Decidueye (frostpeak, ×1); Delibird (frostpeak, ×1); Ducklett (mire, ×1); Espathra (sunscorch, ×1); Farfetch'd (westmarch, ×1); Fearow (sunscorch, ×1); Flamigo (mire, ×1); Fletchinder (westmarch, ×1); Fletchling (westmarch, ×1); Golduck (highlands, ×1); Honchkrow (deep_dark, ×1); Hoothoot (button_isle, ×1); Kilowattrel (deep_sea, ×1); Natu (jungle, ×1); Pidgeotto (highlands, ×1); Pidgey (highlands, ×1); Pidove (southwold, ×1); Pikipek (jungle, ×1); Psyduck (highlands, ×1); Squawkabilly (southwold, ×1); Staraptor (frostpeak, ×1); Swablu (southwold, ×1); Swanna (mire, ×1); Taillow (southwold, ×1); Torchic (highlands, ×1); Toucannon (jungle, ×1); Trumbeak (jungle, ×1); Wingull (shallows, ×1); Xatu (jungle, ×1) | – | Cooked Chicken, Open-Faced Sandwich |
| Raw Cod (`minecraft:cod`) | Alomomola (shallows, ×1); Bruxish (shallows, ×1); Cramorant (shallows, ×0-2); Finizen (shallows, ×0-1); Finneon (shallows, ×1); Mantine (deep_sea, ×0-2); Mantyke (deep_sea, ×0-1); Remoraid (deep_sea, ×1); Veluza (deep_sea, ×1-3); Wishiwashi (shallows, ×1) | Fishing; Loot in Beach (cobblemon), Deep Ocean (cobblemon), Warm Ocean (cobblemon); Loot in Village Plains | Cooked Cod |
| Raw Copper (`minecraft:raw_copper`) | Boldore (westmarch, ×0-2); Copperajah (frostpeak, ×0-2); Roggenrola (westmarch, ×0-1) | Break Copper Ore; Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature) … | Block of Raw Copper, Copper Ingot |
| Raw Iron (`minecraft:raw_iron`) | Bronzor (westmarch, ×0-1); Dhelmise (deep_sea, ×0-2); Durant (basalt, ×0-1); Ferroseed (lush_caves, ×0-1); Klink (westmarch, ×0-1); Magnemite (jungle, ×0-1); Magneton (jungle, ×0-2); Tinkatink (highlands, ×0-1); Tinkatuff (highlands, ×0-2) | Brush suspicious blocks in Prehistoric Birch Tree (worldgen feature); Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature); Brush suspicious blocks in Prehistoric Hydrothermal Vents (worldgen feature) … | Block of Raw Iron, Iron Ingot |
| Raw Mutton (`minecraft:mutton`) | Ampharos (highlands, ×2-4); Dubwool (frostpeak, ×1-3); Flaaffy (highlands, ×1-3); Gogoat (frostpeak, ×1-3); Mareep (highlands, ×1-2) | – | Cooked Mutton, Open-Faced Sandwich |
| Raw Porkchop (`minecraft:porkchop`) | Grumpig (frostpeak, ×1-3); Lechonk (highlands, ×1-2); Oinkologne (highlands, ×1-3); Pignite (highlands, ×1-3); Tepig (highlands, ×1-2) | – | Cooked Porkchop, Open-Faced Sandwich |
| Raw Rabbit (`minecraft:rabbit`) | Buneary (westmarch, ×1); Bunnelby (southwold, ×1); Cinderace (highlands, ×1); Raboot (highlands, ×1); Scorbunny (highlands, ×1) | – | Cooked Rabbit, Open-Faced Sandwich |
| Raw Salmon (`minecraft:salmon`) | Arrokuda (mire, ×1); Barraskewda (mire, ×1); Basculegion (frostpeak, ×1); Basculin (frostpeak, ×1); Buizel (highlands, ×0-1); Dondozo (mire, ×1); Floatzel (highlands, ×0-2); Goldeen (southwold, ×1); Gyarados (jungle, ×1); Magikarp (jungle, ×1); Tatsugiri (mire, ×1) | Fishing; Loot in Village Plains | Cooked Salmon |
| Rawst Berry (`cobblemon:rawst_berry`) | Arcanine (mire, 5%); Camerupt (sunscorch, 5%); Capsakid (sunscorch, 2.5%); Darumaka (jungle, 2.5%); Fletchinder (westmarch, 5%); Fletchling (westmarch, 2.5%); Growlithe (mire, 2.5%); Heatmor (basalt, 5%); Houndoom (basalt, 5%); Magmortar (basalt, 10%); Ninetales (highlands, 5%); Numel (sunscorch, 2.5%); Phantump (westmarch, 2.5%); Poltchageist (sunscorch, 2.5%); Scovillain (sunscorch, 5%); Sinistcha (sunscorch, 5%); Vulpix (highlands, 2.5%) | Break Rawst Berry; Wild berry trees in Badlands, Desert | Berry Juice, Burn Heal, Candied Berries, Cyan Dye |
| Razor Fang (`cobblemon:razor_fang`) | Arbok (sunscorch, 5%); Bruxish (shallows, 5%); Gliscor (basalt, 5%); Golbat (jungle, 5%); Mawile (button_isle, 5%); Seviper (highlands, 5%); Tyrunt (lush_caves, 5%); Zubat (jungle, 2.5%) | Brush suspicious blocks in Prehistoric Sandy Den (worldgen feature); Brush suspicious blocks in Prehistoric Sunscorched Den (worldgen feature); Brush suspicious blocks in Prehistoric Sunscorched Remains (worldgen feature) | Dragon Fang |
| Razz Berry (`cobblemon:razz_berry`) | Braviary (frostpeak, 5%); Gurdurr (westmarch, 5%); Kilowattrel (deep_sea, 5%); Pidove (southwold, 2.5%); Throh (frostpeak, 5%); Timburr (westmarch, 2.5%); Tinkatink (highlands, 2.5%); Tinkatuff (highlands, 5%); Volbeat (mire, 5%) | Break Razz Berry; Wild berry trees in Cherry Grove, Forest | Berry Juice, Candied Berries, Red Dye |
| Red Mushroom (`minecraft:red_mushroom`) | Paras (lush_caves, ×0-2); Parasect (lush_caves, ×1) | Break Red Mushroom | Mushroom Stew, Poké Bait, Rabbit Stew, Suspicious Stew |
| Red Wool (`minecraft:red_wool`) | – | Break Red Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Redstone Dust (`minecraft:redstone`) | Electabuzz (frostpeak, ×0-2); Electivire (frostpeak, ×0-3) | Break Redstone Wire; Crafting (shapeless); Loot in Decaying Crypt Ruins (cobblemon), Mossy Oubliette Ruins (cobblemon), Unstable Cave Ruins (cobblemon); Loot in Mineshaft, Mineshaft Mesa; Loot in Monster Room (worldgen feature) … | brewing: longer potions, Block of Redstone, Cell Battery, Choice Band, Choice Specs, Clock, Compass, Copper Bulb … |
| Relic Coin (`cobblemon:relic_coin`) | Gimmighoul (button_isle, ×24-48) | Break Relic Coin Pouch; Break Relic Coin Sack; Brush suspicious blocks in Decaying Crypt Ruins (cobblemon); Brush suspicious blocks in Deep Crypt (worldgen feature); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon) … | Gold Nugget, Relic Coin Pouch |
| Revival Herb (`cobblemon:revival_herb`) | Leavanny (highlands, 10%); Lilligant (westmarch, 5%); Petilil (westmarch, 2.5%); Sewaddle (highlands, 2.5%); Swadloon (highlands, 5%) | Break Revival Herb; Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon); Loot in Deep Crypt (worldgen feature), Lush Gimmi Tower (cobblemon) … | Heal Powder |
| Rindo Berry (`cobblemon:rindo_berry`) | Barbaracle (deep_sea, 5%); Barboach (southwold, 2.5%); Binacle (deep_sea, 2.5%); Chewtle (highlands, 2.5%); Corsola (westmarch, 5%); Drednaw (highlands, 5%); Finneon (shallows, 2.5%); Geodude (westmarch, 2.5%); Graveler (westmarch, 5%); Panpour (jungle, 2.5%); Relicanth (southwold, 5%); Shellos (shallows, 2.5%); Simipour (jungle, 5%); Wooper (button_isle, 2.5%) | Break Rindo Berry; Wild berry trees in Cherry Grove, Forest, Jungle, Lush Caves, Plains | Berry Juice, Candied Berries, Lime Dye |
| Roasted Leek (`cobblemon:roasted_leek`) | Capsakid (sunscorch, ×0-1); Scovillain (sunscorch, ×0-2) | Campfire; Smelting; Smoker | Leek and Potato Stew |
| Rose Bush (`minecraft:rose_bush`) | Roselia (frostpeak, ×0-1); Roserade (frostpeak, ×1-2) | Break Rose Bush; Use c:fertilizers on your Roselia; Use c:fertilizers on your Roserade | Red Dye |
| Roseli Berry (`cobblemon:roseli_berry`) | Absol (southwold, 5%); Deino (mire, 2.5%); Jangmo-o (jungle, 2.5%); Morpeko (southwold, 5%); Nickit (westmarch, 2.5%); Sableye (button_isle, 5%); Scrafty (sunscorch, 5%); Scraggy (sunscorch, 2.5%); Thievul (westmarch, 5%); Zoroark (highlands, 5%) | Break Roseli Berry; Wild berry trees in Cherry Grove | Berry Juice, Candied Berries, Red Dye |
| Rotten Flesh (`minecraft:rotten_flesh`) | Electrike (highlands, ×0-1); Houndoom (basalt, ×0-2); Houndstone (deep_dark, ×0-2); Joltik (southwold, ×0-1); Lycanroc (frostpeak, ×0-2); Manectric (highlands, ×0-2); Maschiff (westmarch, ×0-1); Mightyena (highlands, ×0-2); Purrloin (southwold, ×0-1); Rattata (button_isle, ×0-1); Salandit (frostpeak, ×0-1); Spinarak (button_isle, ×0-1) | Fishing; Fishing with a Poké Rod; Loot in Desert Pyramid; Loot in Jungle Pyramid; Loot in Monster Room (worldgen feature) … | Mulch |
| Sand (`minecraft:sand`) | Hippopotas (sunscorch, ×0-1); Hippowdon (sunscorch, ×0-2); Sandygast (shallows, ×0-1) | Break Sand; Loot in Desert Pyramid; Use c:tools/brush on your Hippopotas; Use c:tools/brush on your Hippowdon; Use c:tools/brush on your Palossand … | Black Concrete Powder, Blue Concrete Powder, Brown Concrete Powder, Cyan Concrete Powder, Glass, Gray Concrete Powder, Green Concrete Powder, Light Blue Concrete Powder … |
| Shiny Stone (`cobblemon:shiny_stone`) | Togekiss (frostpeak, 10%); Togetic (frostpeak, 5%) | Brush suspicious blocks in Deserted Gimmi Tower (cobblemon); Brush suspicious blocks in Deserted Gimmi Tower (cobblemon), Rooted Gimmi Tower (cobblemon), Temperate Gimmi Tower (cobblemon); Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more … | Shiny Stone Block |
| Shuca Berry (`cobblemon:shuca_berry`) | Glimmet (jungle, 2.5%); Luxio (sunscorch, 5%); Luxray (sunscorch, 10%); Magnemite (jungle, 2.5%); Magneton (jungle, 5%); Orthworm (southwold, 5%); Ponyta (highlands, 2.5%); Salandit (frostpeak, 2.5%); Togedemaru (frostpeak, 5%); Toxel (westmarch, 2.5%); Varoom (westmarch, 2.5%) | Break Shuca Berry; Wild berry trees in Badlands, Desert, Plains | Berry Juice, Brown Dye, Candied Berries |
| Shulker Shell (`minecraft:shulker_shell`) | Cloyster (deep_sea, 10%); Shuckle (lush_caves, 10%) | – | Master Ball, Shulker Box |
| Silk Scarf (`cobblemon:silk_scarf`) | Eevee (westmarch, 5%); Furfrou (southwold, 5%); Furret (southwold, 5%); Minccino (southwold, 2.5%); Sentret (southwold, 2.5%); Skitty (button_isle, 2.5%); Trubbish (southwold, 2.5%) | Crafting | Choice Scarf |
| Slimeball (`minecraft:slime_ball`) | Goomy (mire, ×0-1); Grimer (westmarch, ×0-1); Lickilicky (highlands, ×0-2); Lickitung (highlands, ×0-1); Mareanie (shallows, ×0-1); Pyukumuku (shallows, ×0-2); Solosis (southwold, ×0-1); Tynamo (westmarch, ×0-1) | Crafting (shapeless); Use c:tools/brush on your Goodra; Use c:tools/brush on your Goomy; Use c:tools/brush on your Sliggoo | Binding Band, Lead, Loaded Dice, Magma Cream, Slime Block, Sticky Piston |
| Smithing Template (`minecraft:tide_armor_trim_smithing_template`) | none (cosmetic (an armour trim); elder guardians don't live on the island) | – | Smithing Template |
| Snowball (`minecraft:snowball`) | Abomasnow (frostpeak, ×0-2); Froslass (frostpeak, ×0-2); Frosmoth (frostpeak, ×0-2); Glalie (frostpeak, ×0-2); Vanillish (frostpeak, ×0-2); Vanilluxe (frostpeak, ×0-3) | Break Snow; Break Snow Block; Loot in Ancient City; Loot in Trial Chambers; Use c:tools/brush on your Vanillish … | Casteliacone, Snow Block |
| Soft Sand (`cobblemon:soft_sand`) | Diglett (button_isle, 2.5%); Drilbur (westmarch, 2.5%); Flygon (sunscorch, 10%); Hippopotas (sunscorch, 2.5%); Hippowdon (sunscorch, 5%); Nincada (button_isle, 2.5%); Sandaconda (sunscorch, 5%); Sandshrew (sunscorch, 2.5%); Sandslash (sunscorch, 5%); Sandygast (shallows, 2.5%); Silicobra (sunscorch, 2.5%); Vibrava (sunscorch, 5%) | Break Soft Sand; Crafting | Smooth Rock |
| Spider Eye (`minecraft:spider_eye`) | Joltik (southwold, ×0-1); Spinarak (button_isle, ×0-1); Tarountula (button_isle, ×0-1) | Loot in Desert Pyramid | brewing: Poison, Fermented Spider Eye |
| Stick (`minecraft:stick`) | Bidoof (button_isle, ×0-1); Braixen (sunscorch, ×1); Brambleghast (sunscorch, ×0-2); Delphox (sunscorch, ×1); Grookey (jungle, ×0-1); Grovyle (jungle, ×0-2); Thwackey (jungle, ×0-2); Treecko (jungle, ×0-1) | Break Acacia Leaves; Break Apricorn Leaves; Break Azalea Leaves; Break Birch Leaves; Break Cherry Leaves … | Acacia Fence, Acacia Fence Gate, Acacia Sign, Activator Rail, Apricorn Fence, Apricorn Fence Gate, Apricorn Sign, Armor Stand … |
| Stone (`minecraft:stone`) | Onix (westmarch, ×1-3); Stonjourner (highlands, ×2) | Break Infested Stone; Break Stone; Smelting | Chiseled Stone Bricks, Hard Stone, Quest Book, Redstone Comparator, Redstone Repeater, Smooth Stone, Stone Brick Slab, Stone Brick Stairs … |
| String (`minecraft:string`) | Burmy (southwold, ×0-1); Cascoon (button_isle, ×0-2); Caterpie (button_isle, ×0-1); Charjabug (westmarch, ×0-2); Grubbin (westmarch, ×0-1); Joltik (southwold, ×0-1); Kakuna (button_isle, ×0-2); Larvesta (sunscorch, ×0-1); Leavanny (highlands, ×0-3); Metapod (button_isle, ×0-2); Scatterbug (button_isle, ×0-1); Sewaddle (highlands, ×0-1); Silcoon (button_isle, ×0-2); Spewpa (button_isle, ×0-2); Spinarak (button_isle, ×0-1); Swadloon (highlands, ×0-2); Tarountula (button_isle, ×0-1); Venonat (southwold, ×0-1); Weedle (button_isle, ×0-1); Wurmple (button_isle, ×0-1) | Break Cobweb; Break Tripwire; Brush suspicious blocks in Trail Ruins; Fishing; Fishing with a Poké Rod … | Air Balloon, Binding Band, Bow, Candle, Clear Amulet, Crossbow, Destiny Knot, Fishing Rod … |
| Sugar (`minecraft:sugar`) | Alcremie (westmarch, ×0-2); Milcery (westmarch, ×0-1); Swirlix (southwold, ×0-1) | Crafting (shapeless); Use c:tools/brush on your Alcremie; Use c:tools/brush on your Slurpuff; Use c:tools/brush on your Swirlix | brewing: Swiftness, Berry Sweet, Big Malasada, Blunder Policy, Cake, Candied Apple, Candied Berries, Casteliacone … |
| Sun Stone (`cobblemon:sun_stone`) | Solrock (dripstone, 5%) | Brush suspicious blocks in Prehistoric Eroded Pillar (worldgen feature); Brush suspicious blocks in Prehistoric Sandy Den (worldgen feature); Brush suspicious blocks in Prehistoric Sunscorched Den (worldgen feature); Brush suspicious blocks in Prehistoric Sunscorched Remains (worldgen feature); Brush suspicious blocks in Sunscorched Gimmi Tower (cobblemon) … | Sun Stone Block |
| Sunflower (`minecraft:sunflower`) | – | Break Sunflower; Use c:fertilizers on your Sunflora | Yellow Dye |
| Sweet Berries (`minecraft:sweet_berries`) | Abomasnow (frostpeak, ×2-4); Cherrim (frostpeak, ×2-4); Grotle (highlands, ×2-4); Nickit (westmarch, ×1-3); Ninetales (highlands, ×2-4); Teddiursa (mire, ×1-3); Thievul (westmarch, ×2-4); Ursaring (mire, ×2-4); Vulpix (highlands, ×1-3); Zoroark (highlands, ×2-4); Zorua (highlands, ×1-3) | Use c:fertilizers on your Grotle | Fine Remedy, Jubilife Muffin, Superb Remedy, Whipped Dream |
| Tanga Berry (`cobblemon:tanga_berry`) | Cacnea (sunscorch, 2.5%); Cacturne (sunscorch, 5%); Espathra (sunscorch, 5%); Exeggcute (jungle, 2.5%); Exeggutor (jungle, 5%); Fomantis (jungle, 2.5%); Grumpig (frostpeak, 5%); Inkay (shallows, 2.5%); Krokorok (sunscorch, 5%); Krookodile (sunscorch, 10%); Maschiff (westmarch, 2.5%); Nuzleaf (westmarch, 5%); Seedot (westmarch, 2.5%) | Break Tanga Berry; Wild berry trees in Cherry Grove, Forest, Jungle, Mangrove Swamp | Berry Juice, Candied Berries, Green Dye |
| Terracotta (`minecraft:terracotta`) | Crustle (sunscorch, ×0-2); Dwebble (sunscorch, ×0-1) | Break Terracotta; Smelting | Black Terracotta, Blue Terracotta, Brown Terracotta, Cyan Terracotta, Gray Terracotta, Green Terracotta, Light Blue Terracotta, Light Gray Terracotta … |
| Thunder Stone (`cobblemon:thunder_stone`) | Pichu (westmarch, 2.5%); Pikachu (westmarch, 5%) | Crafting (shapeless); Loot in Crumbling Arch (worldgen feature); Loot in Decaying Crypt Ruins (cobblemon), Deep Crypt (worldgen feature), Deserted Gimmi Tower (cobblemon), Frozen Gimmi Tower (cobblemon), Lush Gimmi Tower (cobblemon), Reclaimed Deserted Monument (cobblemon) and 5 more; Loot in Decaying Crypt Ruins (cobblemon), Rooted Gimmi Tower (cobblemon); Loot in Deep Crypt (worldgen feature), Lush Gimmi Tower (cobblemon) … | Light Ball, Metal Alloy, Thunder Stone Block |
| Turtle Scute (`minecraft:turtle_scute`) | Chewtle (highlands, ×0-1); Drednaw (highlands, ×0-2); Squirtle (highlands, ×0-1); Tirtouga (lush_caves, ×0-2); Turtonator (basalt, ×0-2); Wartortle (highlands, ×0-2) | – | Rocky Helmet, Safety Goggles, Turtle Shell |
| Vines (`minecraft:vine`) | Tangela (jungle, ×0-1); Tangrowth (jungle, ×0-2) | Break Vines; Use c:fertilizers on your Tangela; Use c:fertilizers on your Tangrowth | Mossy Cobblestone, Mossy Stone Bricks |
| Wacan Berry (`cobblemon:wacan_berry`) | Buizel (highlands, 2.5%); Corviknight (deep_dark, 10%); Cramorant (shallows, 5%); Ducklett (mire, 2.5%); Floatzel (highlands, 5%); Goldeen (southwold, 2.5%); Gyarados (jungle, 5%); Magikarp (jungle, 2.5%); Mantine (deep_sea, 5%); Mantyke (deep_sea, 2.5%); Masquerain (mire, 5%); Surskit (mire, 2.5%); Swanna (mire, 5%); Wingull (shallows, 2.5%) | Break Wacan Berry; Wild berry trees in Cherry Grove, Plains, Windswept Hills | Berry Juice, Candied Berries, Yellow Dye |
| Water Stone (`cobblemon:water_stone`) | Panpour (jungle, 2.5%); Simipour (jungle, 5%) | Blast furnace; Break Water Stone Ore; Brush suspicious blocks in Prehistoric Dripstone Oasis (worldgen feature); Brush suspicious blocks in Prehistoric Enhydro Agate (worldgen feature); Brush suspicious blocks in Prehistoric Mossy Pond (worldgen feature) … | Damp Rock, Water Stone Block |
| Wepear Berry (`cobblemon:wepear_berry`) | Araquanid (westmarch, 5%); Bellibolt (mire, 5%); Boltund (westmarch, 5%); Bouffalant (highlands, 5%); Butterfree (button_isle, 5%); Caterpie (button_isle, 2.5%); Charjabug (westmarch, 5%); Dewpider (westmarch, 2.5%); Grubbin (westmarch, 2.5%); Machamp (frostpeak, 10%); Machoke (frostpeak, 5%); Metapod (button_isle, 2.5%); Scyther (westmarch, 2.5%); Tadbulb (mire, 2.5%); Yamper (westmarch, 2.5%) | Break Wepear Berry; Wild berry trees in Plains | Berry Juice, Candied Berries, Lime Dye |
| Wet Sponge (`minecraft:wet_sponge`) | – | Break Wet Sponge | Sponge |
| Wheat Seeds (`minecraft:wheat_seeds`) | Maushold (westmarch, ×0-2); Sunkern (button_isle, ×1); Tandemaus (westmarch, ×0-1) | Break Fern; Break Large Fern; Break Short Grass; Break Tall Grass; Break Wheat … | Miracle Seed |
| White Wool (`minecraft:white_wool`) | Cottonee (highlands, ×1); Dubwool (frostpeak, ×1-2); Eldegoss (frostpeak, ×1-2); Flaaffy (highlands, ×1); Furfrou (southwold, ×1-2); Jumpluff (highlands, ×1-3); Mareep (highlands, ×1-2); Swablu (southwold, ×0-1); Whimsicott (highlands, ×1-2) | Break White Wool; Crafting; Crafting (shapeless); Use c:tools/brush on your Altaria; Use c:tools/brush on your Swablu | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
| Wise Glasses (`cobblemon:wise_glasses`) | Hoothoot (button_isle, 2.5%); Meditite (button_isle, 2.5%); Natu (jungle, 2.5%); Xatu (jungle, 5%) | Crafting | Choice Specs |
| Wither Skeleton Skull (`minecraft:wither_skeleton_skull`) | none (cosmetic here (the skull banner pattern); the Wither can't be built) | – | Banner Pattern |
| Yache Berry (`cobblemon:yache_berry`) | Appletun (mire, 10%); Applin (mire, 2.5%); Bagon (dripstone, 2.5%); Deerling (westmarch, 2.5%); Dragonair (mire, 5%); Dratini (mire, 2.5%); Flapple (mire, 5%); Flygon (sunscorch, 10%); Gliscor (basalt, 5%); Hoppip (highlands, 2.5%); Jumpluff (highlands, 10%); Noibat (jungle, 2.5%); Shelgon (dripstone, 5%); Skiploom (highlands, 5%); Staraptor (frostpeak, 10%); Swablu (southwold, 2.5%); Vibrava (sunscorch, 5%) | Break Yache Berry; Wild berry trees in Jagged Peaks | Berry Juice, Candied Berries, Cyan Dye |
| Yellow Wool (`minecraft:yellow_wool`) | – | Break Yellow Wool; Crafting (shapeless) | Air Balloon, Black Wool, Blue Wool, Brown Wool, Choice Scarf, Covert Cloak, Cyan Wool, Destiny Knot … |
@@ -4,6 +4,7 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.mojang.logging.LogUtils
import dev.cobblesurvival.dev.BiomePreview
import dev.cobblesurvival.dev.OreVeins
import dev.cobblesurvival.permadeath.Permadeath
import dev.cobblesurvival.selftest.SelfTest
import dev.cobblesurvival.world.OnlyPokemon
@@ -92,6 +93,7 @@ class CobbleSurvival {
1
})
.then(BiomePreview.command())
.then(OreVeins.command())
.then(Commands.literal("zone").executes { context ->
val source = context.source
val zone = Zones.at(source.level, BlockPos.containing(source.position))
@@ -0,0 +1,61 @@
package dev.cobblesurvival.dev
import com.mojang.brigadier.builder.LiteralArgumentBuilder
import net.minecraft.commands.CommandSourceStack
import net.minecraft.commands.Commands
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ColumnPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.ChunkPos
import kotlin.math.max
import kotlin.math.min
/**
* Bridge to Regenerating Ore Veins' saved data, by reflection (the mod is CurseForge-only and not a compile
* dependency of the companion mod).
*
* Dev tool: `/cobblesurvival veins unfilled <x1> <z1> <x2> <z2>` counts the loaded chunks in a block rectangle that
* the mod hasn't put veins into yet. It fills a new chunk only while that chunk is loaded, 8 chunks a tick, and
* forgets the rest when the server stops, so a pregeneration run outpaces it; tools/make_world.py loads the island
* again row by row and waits until this count is 0 around each row (loading a row also fully loads the chunks next
* to it). The self-tests use [markMined] to wind a vein block's clock back.
*/
object OreVeins {
private val savedData by lazy { Class.forName("net.stargazer.regenerating_ore_veins.VeinSavedData") }
private val get by lazy { savedData.getMethod("get", ServerLevel::class.java) }
private val isChunkGenerated by lazy { savedData.getMethod("isChunkGenerated", Long::class.javaPrimitiveType) }
private val markMined by lazy { savedData.getMethod("markMined", BlockPos::class.java, Long::class.javaPrimitiveType) }
fun isChunkFilled(level: ServerLevel, chunk: ChunkPos): Boolean =
isChunkGenerated.invoke(get.invoke(null, level), chunk.toLong()) as Boolean
/** Sets when the vein block at [pos] was last mined, in seconds since the epoch (the mod counts real time). */
fun markMined(level: ServerLevel, pos: BlockPos, epochSecond: Long) {
markMined.invoke(get.invoke(null, level), pos, epochSecond)
}
fun command(): LiteralArgumentBuilder<CommandSourceStack> =
Commands.literal("veins")
.requires { it.hasPermission(4) }
.then(Commands.literal("unfilled")
.then(Commands.argument("from", ColumnPosArgument.columnPos())
.then(Commands.argument("to", ColumnPosArgument.columnPos())
.executes { context ->
val level = context.source.server.overworld()
val unfilled = chunks(ColumnPosArgument.getColumnPos(context, "from"),
ColumnPosArgument.getColumnPos(context, "to"))
.count { level.chunkSource.hasChunk(it.x, it.z) && !isChunkFilled(level, it) }
context.source.sendSuccess({ Component.literal("unfilled chunks: $unfilled") }, false)
1
})))
private fun chunks(from: ColumnPos, to: ColumnPos): List<ChunkPos> {
val x0 = min(from.x(), to.x()) shr 4
val x1 = max(from.x(), to.x()) shr 4
val z0 = min(from.z(), to.z()) shr 4
val z1 = max(from.z(), to.z()) shr 4
return (x0..x1).flatMap { x -> (z0..z1).map { z -> ChunkPos(x, z) } }
}
}
@@ -0,0 +1,34 @@
package dev.cobblesurvival.selftest
import com.cobblemon.mod.common.api.drop.ItemDropEntry
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.google.gson.JsonParser
import dev.cobblesurvival.CobbleSurvival
import net.minecraft.gametest.framework.GameTestAssertException
import net.minecraft.resources.ResourceLocation
/**
* Roadmap Phase 4, unique drops: the core data pack gives some Pokémon the drops of mobs the island doesn't have
* (blaze rods, ghast tears, ...) through Cobblemon's species additions (`species_additions/`). This checks that
* Cobblemon really applied every item they add, as tools/drop_audit.py assumes.
*/
object DropTests {
fun all() = listOf(SelfTestCase("drop_additions_apply", 20, ::dropAdditionsApply))
private fun dropAdditionsApply(s: Scenario) {
val additions = s.level.server.resourceManager.listResources("species_additions") { it.path.endsWith(".json") }
.filterKeys { it.namespace == CobbleSurvival.MOD_ID }
s.check(additions.isNotEmpty()) { "the core data pack has no species additions" }
for ((id, resource) in additions) {
val json = resource.openAsReader().use { JsonParser.parseReader(it).asJsonObject }
val target = ResourceLocation.parse(json.get("target").asString)
val species = PokemonSpecies.getByIdentifier(target) ?: throw GameTestAssertException("$id: no species $target")
val drops = species.drops.entries.filterIsInstance<ItemDropEntry>().map { it.item }.toSet()
for (entry in json.getAsJsonObject("drops")?.getAsJsonArray("entries") ?: continue) {
val item = ResourceLocation.parse(entry.asJsonObject.get("item").asString)
s.check(item in drops) { "${species.name} doesn't drop $item, although $id adds it" }
}
}
s.helper.succeed()
}
}
@@ -51,7 +51,7 @@ object SelfTest {
private val cases: List<SelfTestCase> get() =
PermadeathTests.all() + SurvivalRulesTests.all() + ZoneTests.all() + HazardTests.all() + GuardianTests.all() +
VeinTests.all()
VeinTests.all() + DropTests.all()
private var running: List<Scenario> = emptyList()
private var forced: List<ChunkPos> = emptyList()
@@ -1,5 +1,6 @@
package dev.cobblesurvival.selftest
import dev.cobblesurvival.dev.OreVeins
import net.minecraft.core.BlockPos
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.resources.ResourceLocation
@@ -114,9 +115,5 @@ object VeinTests {
BuiltInRegistries.BLOCK.getKey(level.getBlockState(pos).block) == REGENERATOR
/** Moves the vein block's "last mined" time far into the past; the mod keeps it in its saved data. */
private fun rewind(level: ServerLevel, pos: BlockPos) {
val data = Class.forName("net.stargazer.regenerating_ore_veins.VeinSavedData")
val saved = data.getMethod("get", ServerLevel::class.java).invoke(null, level)
data.getMethod("markMined", BlockPos::class.java, Long::class.javaPrimitiveType).invoke(saved, pos, 1L)
}
private fun rewind(level: ServerLevel, pos: BlockPos) = OreVeins.markMined(level, pos, 1L)
}
+272 -48
View File
@@ -1,4 +1,32 @@
[
{
"id": "coal_showcase",
"blocks": [
"minecraft:coal_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 2,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 4,
"fill_factor": 0.8,
"regeneration_interval_seconds": 1200,
"regeneration_interval_jitter": {
"range_min": -120,
"range_max": 120
}
},
{
"id": "coal",
"blocks": [
@@ -103,6 +131,34 @@
"range_max": 120
}
},
{
"id": "copper_showcase",
"blocks": [
"minecraft:copper_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 2,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 5,
"fill_factor": 0.8,
"regeneration_interval_seconds": 1800,
"regeneration_interval_jitter": {
"range_min": -180,
"range_max": 180
}
},
{
"id": "copper",
"blocks": [
@@ -409,6 +465,34 @@
"range_max": 180
}
},
{
"id": "iron_showcase",
"blocks": [
"minecraft:iron_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 2,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 5,
"fill_factor": 0.8,
"regeneration_interval_seconds": 2400,
"regeneration_interval_jitter": {
"range_min": -240,
"range_max": 240
}
},
{
"id": "iron",
"blocks": [
@@ -583,6 +667,34 @@
"range_max": 240
}
},
{
"id": "redstone_showcase",
"blocks": [
"minecraft:redstone_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 1,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.8,
"regeneration_interval_seconds": 2700,
"regeneration_interval_jitter": {
"range_min": -270,
"range_max": 270
}
},
{
"id": "redstone",
"blocks": [
@@ -791,6 +903,34 @@
"range_max": 270
}
},
{
"id": "lapis_showcase",
"blocks": [
"minecraft:lapis_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 1,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.8,
"regeneration_interval_seconds": 2700,
"regeneration_interval_jitter": {
"range_min": -270,
"range_max": 270
}
},
{
"id": "lapis",
"blocks": [
@@ -1171,6 +1311,34 @@
"range_max": 270
}
},
{
"id": "gold_showcase",
"blocks": [
"minecraft:gold_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 2,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 5,
"fill_factor": 0.8,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
"range_min": -360,
"range_max": 360
}
},
{
"id": "gold",
"blocks": [
@@ -1242,10 +1410,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 2,
"attempts": 1,
"attempts": 2,
"min_y": 0,
"max_y": 120,
"chunk_minimum_generation_separation": 6,
"chunk_minimum_generation_separation": 5,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -1324,10 +1492,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 2,
"attempts": 1,
"attempts": 2,
"min_y": -48,
"max_y": -1,
"chunk_minimum_generation_separation": 6,
"chunk_minimum_generation_separation": 5,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -1335,6 +1503,34 @@
"range_max": 360
}
},
{
"id": "emerald_showcase",
"blocks": [
"minecraft:emerald_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 2,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.8,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
"range_min": -450,
"range_max": 450
}
},
{
"id": "emerald",
"blocks": [
@@ -1449,10 +1645,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": 0,
"max_y": 320,
"chunk_minimum_generation_separation": 7,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
@@ -1574,10 +1770,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": -16,
"max_y": -1,
"chunk_minimum_generation_separation": 7,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
@@ -1604,10 +1800,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 1,
"attempts": 1,
"min_y": -64,
"max_y": 64,
"chunk_minimum_generation_separation": 8,
"attempts": 4,
"min_y": 0,
"max_y": 40,
"chunk_minimum_generation_separation": 10,
"fill_factor": 0.7,
"regeneration_interval_seconds": 7200,
"regeneration_interval_jitter": {
@@ -1632,10 +1828,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 1,
"attempts": 1,
"attempts": 3,
"min_y": -64,
"max_y": -1,
"chunk_minimum_generation_separation": 7,
"max_y": -24,
"chunk_minimum_generation_separation": 10,
"fill_factor": 0.7,
"regeneration_interval_seconds": 5400,
"regeneration_interval_jitter": {
@@ -1660,10 +1856,10 @@
"shape": "sphere",
"min_radius": 1,
"max_radius": 2,
"attempts": 1,
"min_y": -64,
"max_y": 64,
"chunk_minimum_generation_separation": 6,
"attempts": 3,
"min_y": 0,
"max_y": 40,
"chunk_minimum_generation_separation": 8,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -1688,10 +1884,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"min_y": -64,
"max_y": 32,
"chunk_minimum_generation_separation": 10,
"attempts": 2,
"min_y": 0,
"max_y": 40,
"chunk_minimum_generation_separation": 14,
"fill_factor": 0.7,
"regeneration_interval_seconds": 10800,
"regeneration_interval_jitter": {
@@ -1890,10 +2086,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 4,
"min_y": 0,
"max_y": 64,
"chunk_minimum_generation_separation": 8,
"max_y": 40,
"chunk_minimum_generation_separation": 10,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -1918,10 +2114,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"min_y": -64,
"attempts": 4,
"min_y": -16,
"max_y": -1,
"chunk_minimum_generation_separation": 8,
"chunk_minimum_generation_separation": 10,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -2137,6 +2333,34 @@
"range_max": 360
}
},
{
"id": "water_stone_showcase",
"blocks": [
"cobblemon:water_stone_ore"
],
"weights": [
1
],
"dimension_whitelist": [
"minecraft:overworld"
],
"area_whitelist": [
"selftest_nowhere"
],
"shape": "sphere",
"min_radius": 2,
"max_radius": 2,
"attempts": 1,
"min_y": 0,
"max_y": 0,
"chunk_minimum_generation_separation": 8,
"fill_factor": 0.8,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
"range_min": -360,
"range_max": 360
}
},
{
"id": "water_stone",
"blocks": [
@@ -2334,10 +2558,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"min_y": -64,
"max_y": 64,
"chunk_minimum_generation_separation": 8,
"attempts": 4,
"min_y": 0,
"max_y": 40,
"chunk_minimum_generation_separation": 10,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -2796,10 +3020,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": 0,
"max_y": 120,
"chunk_minimum_generation_separation": 8,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -2878,10 +3102,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": -48,
"max_y": -1,
"chunk_minimum_generation_separation": 8,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -3003,10 +3227,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": 0,
"max_y": 320,
"chunk_minimum_generation_separation": 8,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -3128,10 +3352,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": -16,
"max_y": -1,
"chunk_minimum_generation_separation": 8,
"chunk_minimum_generation_separation": 6,
"fill_factor": 0.7,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
@@ -3253,10 +3477,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": 0,
"max_y": 320,
"chunk_minimum_generation_separation": 9,
"chunk_minimum_generation_separation": 7,
"fill_factor": 0.7,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
@@ -3378,10 +3602,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 2,
"min_y": -16,
"max_y": -1,
"chunk_minimum_generation_separation": 9,
"chunk_minimum_generation_separation": 7,
"fill_factor": 0.7,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
@@ -3406,10 +3630,10 @@
"shape": "sphere",
"min_radius": 0,
"max_radius": 1,
"attempts": 1,
"attempts": 3,
"min_y": -64,
"max_y": -1,
"chunk_minimum_generation_separation": 9,
"max_y": -24,
"chunk_minimum_generation_separation": 12,
"fill_factor": 0.7,
"regeneration_interval_seconds": 4500,
"regeneration_interval_jitter": {
+1 -1
View File
@@ -42,7 +42,7 @@ hash = "a6e9d717e2f73e463b25b1eacfbff43304fd8993937d8c002f9629f24ebcc221"
[[files]]
file = "config/regenerating_ore_veins/veins.json"
hash = "a671bcfc92c200a93f16bc92d46426b8d5f2bfd21e57af463a821c4fa3755d2c"
hash = "ead417ded7b2867aadf6946c5f919b95fb2001d5207c1c39753872a2676a5d79"
[[files]]
file = "config/worldgen_editor/presets/cobblesurvival_island.json"
+1 -1
View File
@@ -6,7 +6,7 @@ pack-format = "packwiz:1.1.0"
[index]
file = "index.toml"
hash-format = "sha256"
hash = "37b01e238f83c754e3eb7093432815272645949ebcbc623ae5cde213a30e2155"
hash = "d3263f05660d4365aad10cef3f235c204ddc497118675165714f95d378de3d1f"
[versions]
minecraft = "1.21.1"
+155
View File
@@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""Phase 4 drop audit: every crafting input that comes from a creature must have a source on the island.
Only Pokémon live on the island, so whatever a vanilla mob would drop has to come from somewhere else:
a Pokémon's drop, a chest, a vein, a craft. This builds the field guide's model of the pack (no server; it
uses the last KubeJS recipe export, so run tools/fieldguide/build.py after changing KubeJS scripts) and audits
every item that a Pokémon or a vanilla mob drops and that a recipe consumes (crafting, smelting, smithing,
the pack's KubeJS recipes) or that brewing needs (brewing lives in code, so BREWING lists it).
Writes docs/pokemon-drops.md: per item, the wild Pokémon that drop it with their zones and chances, its other
sources, and what consumes it. Fails when an audited item has no source on the island, unless NO_SOURCE_OK
says why that's intended, and when the pack's species additions give drops to a Pokémon whose zone spawn has
drops of its own (a spawn's drops replace the species' drops, so the addition would never apply in the wild).
Usage: tools/drop_audit.py
"""
import json
import sys
from collections import defaultdict
from pathlib import Path
sys.dont_write_bytecode = True
sys.path.insert(0, str(Path(__file__).resolve().parent))
from fieldguide import datasource, kubejs_export # noqa: E402
from fieldguide.model import Model # noqa: E402
ROOT = Path(__file__).resolve().parent.parent
OUT = ROOT / "docs/pokemon-drops.md"
POOLS = ROOT / "datapacks/core/data/cobblesurvival/spawn_pool_world"
ADDITIONS = ROOT / "datapacks/core/data/cobblesurvival/species_additions"
VEIN_SOURCES = ROOT / "world/vein-sources.json"
# Brewing ingredients and the brewing stand's fuel (vanilla code, not data).
BREWING = {
"minecraft:nether_wart": "brewing: Awkward Potion", "minecraft:blaze_powder": "brewing: Strength; stand fuel",
"minecraft:ghast_tear": "brewing: Regeneration", "minecraft:magma_cream": "brewing: Fire Resistance",
"minecraft:glistering_melon_slice": "brewing: Healing", "minecraft:rabbit_foot": "brewing: Leaping",
"minecraft:spider_eye": "brewing: Poison", "minecraft:fermented_spider_eye": "brewing: Weakness, corrupting",
"minecraft:phantom_membrane": "brewing: Slow Falling", "minecraft:pufferfish": "brewing: Water Breathing",
"minecraft:golden_carrot": "brewing: Night Vision", "minecraft:turtle_helmet": "brewing: Turtle Master",
"minecraft:sugar": "brewing: Swiftness", "minecraft:redstone": "brewing: longer potions",
"minecraft:glowstone_dust": "brewing: stronger potions", "minecraft:gunpowder": "brewing: splash potions",
"minecraft:dragon_breath": "brewing: lingering potions", "minecraft:breeze_rod": "brewing: Wind Charging",
"minecraft:slime_block": "brewing: Oozing", "minecraft:cobweb": "brewing: Weaving",
}
# Audited items that may stay without a source, and why.
NO_SOURCE_OK = {
"cold_sweat:chameleon_molt": "Cold Sweat's chameleon armour and Thermolith are not part of the pack's progression",
"minecraft:dragon_breath": "the End's dragon is the only source by design (the End is reachable)",
"minecraft:tide_armor_trim_smithing_template": "cosmetic (an armour trim); elder guardians don't live on the island",
"minecraft:wither_skeleton_skull": "cosmetic here (the skull banner pattern); the Wither can't be built",
}
def zones_by_species():
zones = defaultdict(set)
for pool in sorted(POOLS.glob("*.json")):
for spawn in json.loads(pool.read_text()).get("spawns", []):
species = spawn["pokemon"].split()[0].split(":")[-1]
zones[f"cobblemon:{species}"].add(pool.stem)
return zones
def overridden_additions():
"""Species additions with drops whose target has a zone spawn with its own drops."""
targets = {json.loads(f.read_text())["target"].split(":")[-1]: f.name for f in sorted(ADDITIONS.glob("*.json"))
if "drops" in json.loads(f.read_text())}
clashes = []
for pool in sorted(POOLS.glob("*.json")):
for spawn in json.loads(pool.read_text()).get("spawns", []):
species = spawn["pokemon"].split()[0].split(":")[-1]
if species in targets and "drops" in spawn:
clashes.append(f"{targets[species]}: spawn {spawn['id']} has drops of its own")
return clashes
def consumers(model):
used = defaultdict(set)
for rid, recipe in model.recipes.items():
for slot in recipe.get("slots") or []:
for item in (slot or {}).get("items", []):
used[item].add(recipe["result"])
return used
def main():
stack = datasource.build_stack(log=lambda msg: None)
kubejs = kubejs_export.load()
if not kubejs or kubejs["stale"]:
print("note: the KubeJS recipe export is missing or older than the pack; run tools/fieldguide/build.py to refresh it")
model = Model(stack, log=lambda msg: None, extras=[VEIN_SOURCES] if VEIN_SOURCES.exists() else [], kubejs=kubejs)
zones = zones_by_species()
used = consumers(model)
audited = {}
for key, sources in model.sources.items():
if not key.startswith("item:"):
continue
item = key[5:]
if not any(s["kind"] in ("pokemon", "mob") for s in sources):
continue
uses = sorted(model.item_name(r) for r in used.get(item, ()))
if item in BREWING:
uses.insert(0, BREWING[item])
if uses:
audited[item] = (sources, uses)
rows, missing = [], []
for item in sorted(audited, key=model.item_name):
sources, uses = audited[item]
pokemon = defaultdict(set)
for s in sources:
if s["kind"] == "pokemon" and s["status"] == "available":
where = ", ".join(sorted(zones.get(s["species"], ()))) or "?"
pokemon[f"{model.species_name(s['species'])} ({where}, {s['chance']})"].add(1)
others = sorted({s["text"] for s in sources if s["status"] == "available" and s["kind"] not in ("pokemon", "mob")})
if not pokemon and not others:
if item not in NO_SOURCE_OK:
missing.append(item)
rows.append((model.item_name(item), item, sorted(pokemon), others, uses))
lines = [
"# Pokémon drops and what they're for",
"",
"Generated by `tools/drop_audit.py` (roadmap Phase 4, \"unique drops\"): every item a Pokémon or a vanilla mob "
"drops that a recipe or brewing consumes. Only Pokémon live on the island, so a mob's drop needs another source. "
"Zones are the wild Pokémon's home zones (`docs/zone-species.md`); chances are per defeat. Other sources are cut "
"to five.",
"",
"| Item | Wild Pokémon that drop it | Other sources | Consumed by |",
"| --- | --- | --- | --- |",
]
for name, item, pokemon, others, uses in rows:
source_note = "" if pokemon or others else ("**none**" if item not in NO_SOURCE_OK else f"none ({NO_SOURCE_OK[item]})")
lines.append(f"| {name} (`{item}`) | {'; '.join(pokemon) or source_note or '–'} | "
f"{'; '.join(others[:5]) + (' …' if len(others) > 5 else '') or '–'} | {', '.join(uses[:8])}"
f"{' …' if len(uses) > 8 else ''} |")
OUT.write_text("\n".join(lines) + "\n")
print(f"audited {len(rows)} items; wrote {OUT.relative_to(ROOT)}")
clashes = overridden_additions()
if missing:
print("NO SOURCE ON THE ISLAND:")
for item in missing:
print(f" - {item}: used by {', '.join(audited[item][1][:6])}")
if clashes:
print("SPECIES ADDITIONS THAT NEVER APPLY IN THE WILD:")
for clash in clashes:
print(f" - {clash}")
if missing or clashes:
sys.exit(1)
print("every audited item has a source")
if __name__ == "__main__":
main()
+5 -2
View File
@@ -18,7 +18,8 @@ Writes build/field-guide/:
Usage: tools/fieldguide/build.py [--out DIR] [--no-icons] [--no-server] [--from-json FILE] [--extra FILE ...]
--no-server never start Minecraft: use the last KubeJS recipe export even if the pack changed since
--from-json skip extraction and render an existing fieldguide.json (e.g. one a runtime exporter wrote)
--extra add sources from a JSON file (format in docs/field-guide.md), e.g. ore veins or trades
--extra add sources from a JSON file (format in docs/field-guide.md), e.g. trades; the ore veins
(world/vein-sources.json, written by tools/zone_ores.py) are always added
"""
import argparse
import json
@@ -33,6 +34,7 @@ from fieldguide.icons import Icons # noqa: E402
from fieldguide.model import Model # noqa: E402
ROOT = Path(__file__).resolve().parent.parent.parent
VEIN_SOURCES = ROOT / "world/vein-sources.json" # the regenerating ore veins (tools/zone_ores.py), always read
def main():
@@ -52,7 +54,8 @@ def main():
else:
print("reading the pack's data")
stack = datasource.build_stack(log=_log_once())
model = Model(stack, log=lambda msg: print(" " + msg), extras=args.extra, kubejs=_kubejs(args.no_server))
extras = [VEIN_SOURCES] + args.extra if VEIN_SOURCES.exists() else args.extra
model = Model(stack, log=lambda msg: print(" " + msg), extras=extras, kubejs=_kubejs(args.no_server))
icons = {}
if not args.no_icons:
wanted = set(model.mod_items) | _vanilla_mentions(model)
+12 -1
View File
@@ -193,6 +193,14 @@ class Model:
}
for e in (d.get("drops") or {}).get("entries", []):
self.referenced.add(norm_id(e["item"]))
# Species additions (data/<ns>/species_additions/) replace the fields they set; drops is the one the guide shows.
for _, rel in sorted(self.stack.ids("species_additions").items()):
d = self.stack.json(rel) or {}
target = self.species.get(norm_id(d.get("target", "")))
if target is not None and "drops" in d:
target["drops"] = d["drops"]
for e in d["drops"].get("entries", []):
self.referenced.add(norm_id(e["item"]))
def species_name(self, sid):
return self.species.get(sid, {}).get("name") or sid.split(":")[-1].title()
@@ -563,9 +571,12 @@ class Model:
text = {"biome": "Spawns in " + _join([self.biome_name(b) for b in where]),
"structure": "Spawns in " + _join([self.structure_name(s) for s in where]),
"special": _join(where).capitalize()}[e["kind"]]
if not self.island.mob_allowed(mob):
text += " (but only Pokémon live on the island)"
self.add(f"mob:{mob}", e["kind"], text, base=e["status"])
for mob, (item, note) in self.island.item_mobs.items():
self.add(f"mob:{mob}", "item", note.capitalize(), needs=[[f"item:{item}"]])
if self.island.mob_allowed(mob):
self.add(f"mob:{mob}", "item", note.capitalize(), needs=[[f"item:{item}"]])
def _spawn_nodes(self):
self.spawn_by_species = defaultdict(list)
+10
View File
@@ -515,6 +515,16 @@ class Island:
self._add_mob(mob, "special", note, st)
elif kind == "item":
self.item_mobs[mob] = (req, note)
# The companion mod lets only Cobblemon's entities join a world (world/OnlyPokemon.kt), apart from the
# entity type tag cobblesurvival:allowed_vanilla_mobs; every other mob never appears, whatever spawns it.
self.allowed_mobs = self.tags["entity_type"].resolve("#cobblesurvival:allowed_vanilla_mobs")
for mob, entries in self.mobs.items():
if not self.mob_allowed(mob):
for e in entries:
e["status"] = "unavailable"
def mob_allowed(self, mob):
return mob.startswith("cobblemon:") or mob in self.allowed_mobs
def _add_mob(self, mob, kind, where, status):
lst = self.mobs.setdefault(mob, [])
+34 -2
View File
@@ -7,7 +7,9 @@
type and gamerules, and pregenerate a circle of `pregen_radius` around
0,0 (the island plus a strip of sea; the sea corners inside the square
border generate when someone gets there).
3. In the same session: place the showcase ore veins (world/zones.json →
3. In the same session: load the circle again row by row until Regenerating
Ore Veins has put veins into every chunk (it only fills a new chunk while
it is loaded, 8 a tick, and Chunky is faster), place the showcase ore veins (world/zones.json →
"ores", tiers with "showcase": one vein sticking out of the ground near
its zone's sample point, so players see what a regenerating vein looks
like), save, measure where the land ends (tools/world_report.py) and set
@@ -23,9 +25,12 @@ Usage: tools/make_world.py
"""
import argparse
import json
import math
import re
import shutil
import subprocess
import sys
import time
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
@@ -41,6 +46,32 @@ SKIP = shutil.ignore_patterns("playerdata", "advancements", "stats", "session.lo
SHOWCASE_OFFSETS = [(16, 0), (0, 16), (-16, 0), (0, -16), (24, 24), (-24, -24)]
def fill_veins(server, radius):
"""Keep each chunk row of the pregenerated circle loaded until the vein mod has filled it; returns chunks left."""
# A forced row also fully loads the two chunks around it (some of them new, past the circle's edge), so the wait
# counts the loaded, unfilled chunks in the row and two chunks around it.
started, left, rows = time.time(), 0, radius // 16 + 1
for cz in range(-rows, rows + 1):
half = math.isqrt(max(0, rows * rows - cz * cz))
area = f"{-half * 16} {cz * 16} {half * 16 + 15} {cz * 16 + 15}"
around = f"{-half * 16 - 32} {cz * 16 - 32} {half * 16 + 47} {cz * 16 + 47}"
server.command(f"forceload add {area}")
deadline = time.time() + 60
while True:
reply = server.command(f"cobblesurvival veins unfilled {around}")
match = re.search(r"unfilled chunks: (\d+)", reply)
if not match:
raise RuntimeError(f"veins unfilled: unexpected reply {reply!r}")
unfilled = int(match[1])
if unfilled == 0 or time.time() > deadline:
break
time.sleep(0.5)
server.command(f"forceload remove {area}")
left += unfilled
print(f"veins filled in {time.time() - started:.0f}s" + (f"; {left} chunks left unfilled" if left else ""))
return left
def place_showcases(server):
"""One hand-placed vein per showcase tier, half sunk into the ground near the zone's sample point."""
plan = json.loads((ROOT / "world/zones.json").read_text())
@@ -56,7 +87,7 @@ def place_showcases(server):
x, z = spot
server.command(f"forceload add {x} {z}")
reply = server.command(f"execute in minecraft:overworld positioned {x} 0 {z} positioned over world_surface "
f"positioned ~ ~-1 ~ run regenerating_ore_veins place {tier}").strip()
f"positioned ~ ~-1 ~ run regenerating_ore_veins place {tier}_showcase").strip()
server.command(f"forceload remove {x} {z}")
print(f" showcase {tier} at {x},{z}: {reply[:100]}")
@@ -101,6 +132,7 @@ def main():
print(f" {server.command(f'gamerule {rule} {str(value).lower()}').strip()}")
seconds = server.pregenerate(0, 0, recipe["pregen_radius"], shape="circle")
print(f"pregeneration finished in {seconds:.0f}s")
fill_veins(server, recipe["pregen_radius"])
place_showcases(server)
server.command("save-all flush")
cx, cz, size = border_for(world, recipe)
+5 -3
View File
@@ -8,9 +8,10 @@ instance are left alone. Close the instance in Prism before syncing.
When build/world-template exists (tools/make_world.py), it is copied into the
instance as the save "Cobblemon Survival Island" unless that save already
exists; --replace-world overwrites it.
exists; --replace-world overwrites it, --save-name puts it into another save
folder instead (e.g. next to a save someone has played).
Usage: tools/prism_instance.py [--name NAME] [--prism-dir DIR] [--memory MB] [--replace-world]
Usage: tools/prism_instance.py [--name NAME] [--prism-dir DIR] [--memory MB] [--replace-world] [--save-name NAME]
"""
import argparse
import json
@@ -64,6 +65,7 @@ def main():
parser.add_argument("--prism-dir", type=Path, help="Prism data folder (auto-detected)")
parser.add_argument("--memory", type=int, default=6144, help="max heap in MB")
parser.add_argument("--replace-world", action="store_true", help="overwrite the island save in the instance")
parser.add_argument("--save-name", default="Cobblemon Survival Island", help="save folder for the world template")
args = parser.parse_args()
prism = args.prism_dir or next((d for d in PRISM_DIRS if (d / "instances").is_dir()), None)
@@ -81,7 +83,7 @@ def main():
write_components(instance / "mmc-pack.json", pack["versions"])
sync("client", game, stage)
template, save = ROOT / "build/world-template", game / "saves" / "Cobblemon Survival Island"
template, save = ROOT / "build/world-template", game / "saves" / args.save_name
if (template / "level.dat").exists():
if save.exists() and not args.replace_world:
print(f"kept existing save {save.name} (use --replace-world to overwrite it)")
+71 -41
View File
@@ -4,11 +4,14 @@
* Ore scan: every block in every stored chunk is checked. Ore ("*_ore",
ancient debris, raw ore blocks from large veins) is only allowed as part of
a regenerating vein (Regenerating Ore Veins' saved data), and each vein's
blocks must lie in the zone of its ore tier (world/zones.json → "ores"),
or at most two radii from a block of the same vein that does: the mod
checks the biome only at a vein's centre, so its edge can reach over the
border of a cave zone. Untracked ore fails the check, and so (except with
--sample) does an ore tier without any vein.
blocks must lie in the zone of its ore tier (world/zones.json → "ores").
A surface tier's blocks must lie in its zone's grid cells (the mod checks
every block against the zone's boxes; at a cave border a vein can reach
into the cave biome). A cave tier's blocks must lie within two biome cells
(8 blocks) of its cave biome: the mod checks the biome only at a vein's
centre, and Minecraft blends biomes over a few blocks. Untracked ore fails
the check, and so (except with --sample) do an ore tier without any vein
and a chunk the mod never put veins into.
* Biome set: every biome stored in any chunk section (surface and caves)
must be listed in world/biomes.json ("allowed" or "water").
* End access: at least one stronghold must start inside the world border.
@@ -48,6 +51,8 @@ import zone_grid # noqa: E402
ROOT = Path(__file__).resolve().parent.parent
ORE = re.compile(r"(_ore|:ancient_debris|:raw_(iron|copper|gold)_block)$")
CAVE_BIOMES = sorted(zone_grid.load().caves)
NEAR_CELLS = 2 # biome cells (4 blocks) around a vein block in which its cave biome may lie
# Blocks the regenerating veins are made of (amethyst isn't "ore" by name but is a tier).
VEIN_BLOCKS = {b for v in json.loads((ROOT / "pack/config/regenerating_ore_veins/veins.json").read_text())
for b in v["blocks"]}
@@ -63,7 +68,8 @@ def scan_region(path):
floor = np.full((512, 512), -10_000, dtype=np.int16)
top = np.full((512, 512), -10_000, dtype=np.int16)
biome = np.full((128, 128), -1, dtype=np.int16)
names, ores, chunks, present, strongholds, ore_at = {}, {}, 0, {}, [], []
names, ores, chunks, present, strongholds, ore_at, full = {}, {}, 0, {}, [], [], []
caves = {} # (chunk x, chunk z) -> 96x4x4 biome cells (y, z, x): index into CAVE_BIOMES + 1, 0 = no cave biome
loot = {"lootr": 0, "unconverted": 0, "unconverted_at": []}
for cx, cz, chunk in anvil.region_chunks(path):
for be in chunk.get("block_entities", []):
@@ -77,6 +83,7 @@ def scan_region(path):
if not str(chunk.get("Status", "")).endswith("full"):
continue
chunks += 1
full.append((cx, cz))
ox, oz = (cx - rx * 32) * 16, (cz - rz * 32) * 16
of = anvil.heightmap(chunk, "OCEAN_FLOOR")
mb = anvil.heightmap(chunk, "MOTION_BLOCKING")
@@ -88,6 +95,13 @@ def scan_region(path):
for section in sections.values():
for name in section.get("biomes", {}).get("palette", []):
present[name] = present.get(name, 0) + 1
biome_palette = section.get("biomes", {}).get("palette", [])
if any(b in CAVE_BIOMES for b in biome_palette):
biome_palette, biome_indices = anvil.section_biomes(section)
ids = np.array([CAVE_BIOMES.index(b) + 1 if b in CAVE_BIOMES else 0 for b in biome_palette], dtype=np.int8)
cells = caves.setdefault((cx, cz), np.zeros((96, 4, 4), dtype=np.int8))
y0 = (section["Y"] * 16 - anvil.MIN_Y) // 4
cells[y0:y0 + 4] = ids[biome_indices].reshape(4, 4, 4)
palette, indices = anvil.section_blocks(section)
entries = section.get("block_states", {}).get("palette", [])
hits = {i: name for i, name in enumerate(palette)
@@ -116,7 +130,20 @@ def scan_region(path):
palette, indices = decoded[y // 16]
name = palette[int(indices[((y % 16) // 4) * 16 + qz * 4 + qx])]
biome[oz // 4 + qz, ox // 4 + qx] = names.setdefault(name, len(names))
return rx, rz, floor, top, biome, list(names), ores, chunks, present, strongholds, loot, ore_at
# Which cave biomes lie within NEAR_CELLS biome cells of each vein block (chunks of this region only).
near_at = []
for x, y, z, name, biome_name in ore_at:
near = set()
qx0, qy0, qz0 = x >> 2, (y - anvil.MIN_Y) >> 2, z >> 2
for qx in range(qx0 - NEAR_CELLS, qx0 + NEAR_CELLS + 1):
for qz in range(qz0 - NEAR_CELLS, qz0 + NEAR_CELLS + 1):
cells = caves.get((qx >> 2, qz >> 2))
if cells is None:
continue
column = cells[max(0, qy0 - NEAR_CELLS):qy0 + NEAR_CELLS + 1, qz & 3, qx & 3]
near.update(CAVE_BIOMES[i - 1] for i in np.unique(column) if i)
near_at.append((x, y, z, name, biome_name, tuple(sorted(near))))
return rx, rz, floor, top, biome, list(names), ores, chunks, present, strongholds, loot, near_at, full
# Entities that aren't mobs: decorations, vehicles, and projectiles (a trial chamber's dispenser trap fires
@@ -147,11 +174,12 @@ def analyse(world):
floor = np.full((h, w), -10_000, dtype=np.int16)
top = np.full((h, w), -10_000, dtype=np.int16)
biome = np.full((h // 4, w // 4), -1, dtype=np.int16)
names, ores, chunks, present, strongholds, ore_at = [], {}, 0, {}, [], []
names, ores, chunks, present, strongholds, ore_at, full = [], {}, 0, {}, [], [], []
loot = {"lootr": 0, "unconverted": 0, "unconverted_at": []}
with ProcessPoolExecutor(max_workers=os.cpu_count()) as pool:
for rx, rz, f, t, b, local, o, n, pr, sh, lt, oa in pool.map(scan_region, regions):
for rx, rz, f, t, b, local, o, n, pr, sh, lt, oa, fc in pool.map(scan_region, regions):
ore_at += oa
full += fc
for k, v in lt.items():
loot[k] += v
strongholds += sh
@@ -171,19 +199,26 @@ def analyse(world):
for k, v in counts.items():
entities[k] = entities.get(k, 0) + v
return {"origin": (x0 * 512, z0 * 512), "floor": floor, "top": top, "biome": biome,
"biome_names": names, "ores": ores, "ore_at": ore_at, "chunks": chunks, "sections_per_biome": present,
"biome_names": names, "ores": ores, "ore_at": ore_at, "full_chunks": full, "chunks": chunks,
"sections_per_biome": present,
"strongholds": strongholds, "entities": entities, "loot": loot}
def read_veins(world):
"""{(x, y, z): vein id} from Regenerating Ore Veins' saved data (empty if the mod never ran)."""
"""({(x, y, z): vein id}, {(chunk x, chunk z) the mod has filled}) from Regenerating Ore Veins' saved data."""
path = Path(world, "data/regenerating_ore_veins_veins.dat")
if not path.exists():
return {}
return {}, set()
import gzip
data = anvil.parse_nbt(gzip.decompress(path.read_bytes()))
data = data.get("data", data)
filled = set()
for packed in data.get("GeneratedChunks", []): # ChunkPos.toLong: x in the low 32 bits, z in the high
packed = int(packed)
x, z = packed & 0xFFFFFFFF, (packed >> 32) & 0xFFFFFFFF
filled.add((x - (1 << 32) if x >= 1 << 31 else x, z - (1 << 32) if z >= 1 << 31 else z))
veins = {}
for entry in data.get("data", data).get("Entries", []):
for entry in data.get("Entries", []):
pos = entry["Pos"]
if isinstance(pos, dict):
key = (pos["X"], pos["Y"], pos["Z"])
@@ -193,46 +228,41 @@ def read_veins(world):
else:
key = tuple(int(v) for v in pos)
veins[key] = entry.get("VeinId", "")
return veins
return veins, filled
def check_veins(world, ore_at, sample):
def check_veins(world, ore_at, full_chunks, sample):
"""Every ore block belongs to a tracked vein in its tier's zone; returns (blocks per tier and zone, problems)."""
plan = json.loads((ROOT / "world/zones.json").read_text())
grid = zone_grid.load()
tier_zone = {}
for tier, spec in plan["ores"].items():
tier_zone[tier] = tier_zone[f"{tier}_deep"] = (spec["zone"], spec["radius"][1])
veins = read_veins(world)
per_tier, untracked, stray = {}, {}, []
blocks = {(x, y, z): (name, biome) for x, y, z, name, biome in ore_at}
zone_of = {pos: grid.zone_at(pos[0], pos[2], biome) for pos, (_, biome) in blocks.items()}
for pos, (name, _) in blocks.items():
vein = veins.get(pos)
cave_biome = {c["id"]: c["biome"] for c in plan["caves"]}
veins, filled = read_veins(world)
per_tier, untracked, stray = {}, {}, {}
for x, y, z, name, biome, near_caves in ore_at:
vein = veins.get((x, y, z))
if vein is None:
if ORE.search(name): # amethyst outside a vein is a natural geode
untracked[name] = untracked.get(name, 0) + 1
continue
tier = vein[:-5] if vein.endswith("_deep") else vein
tier = vein.removesuffix("_showcase").removesuffix("_deep")
zone = grid.zone_at(x, z, biome) or "none"
counts = per_tier.setdefault(tier, {})
counts[zone_of[pos] or "none"] = counts.get(zone_of[pos] or "none", 0) + 1
want, radius = tier_zone.get(vein, (None, 0))
if zone_of[pos] == want:
continue
reach = 2 * radius
near = any(veins.get(q) == vein and zone_of.get(q) == want
for q in ((pos[0] + dx, pos[1] + dy, pos[2] + dz) for dx in range(-reach, reach + 1)
for dy in range(-reach, reach + 1) for dz in range(-reach, reach + 1)))
if not near:
stray.append((vein, pos, zone_of[pos]))
counts[zone] = counts.get(zone, 0) + 1
want = plan["ores"].get(tier, {}).get("zone")
if want in cave_biome:
ok = zone == want or cave_biome[want] in near_caves
else:
ok = want is not None and grid.zone_at(x, z) == want
if not ok:
stray.setdefault((vein, zone, want), []).append((x, y, z))
problems = [f"{n} {name} outside any regenerating vein" for name, n in sorted(untracked.items())]
if not sample:
problems += [f"ore tier {tier} has no vein in the world" for tier in plan["ores"] if tier not in per_tier]
by_vein = {}
for vein, pos, zone in stray:
by_vein.setdefault((vein, zone), []).append(pos)
problems += [f"{len(at)} blocks of vein {vein} in zone {zone}, not {tier_zone.get(vein, ('(no tier)',))[0]} "
f"(e.g. {at[0]})" for (vein, zone), at in sorted(by_vein.items(), key=str)]
unfilled = [c for c in full_chunks if c not in filled]
if unfilled:
problems.append(f"{len(unfilled)} chunks never got their ore veins (e.g. chunk {unfilled[0]})")
problems += [f"{len(at)} blocks of vein {vein} in zone {zone}, not {want or '(no tier)'} (e.g. {at[0]})"
for (vein, zone, want), at in sorted(stray.items(), key=str)]
return per_tier, problems
@@ -427,7 +457,7 @@ def main():
biomes = json.loads((ROOT / "world/biomes.json").read_text())
listed = set(biomes["allowed"]) | set(biomes["water"])
unlisted = {b: n for b, n in data["sections_per_biome"].items() if b not in listed}
vein_counts, vein_problems = check_veins(args.world, data["ore_at"], args.sample)
vein_counts, vein_problems = check_veins(args.world, data["ore_at"], data["full_chunks"], args.sample)
report = {
"chunks_scanned": data["chunks"],
"ore_blocks": {k: v for k, v in data["ores"].items() if ORE.search(k) or k in VEIN_BLOCKS},
+30 -1
View File
@@ -12,11 +12,15 @@ world/zones.json → "ores" lists the tiers. This tool writes pack/config/regene
of the cave biomes, which are zones of their own; a cave tier's veins to its cave biome. The mod checks
the area for every block and the biome at a vein's centre. One vein only for the self-tests comes
last ("selftest", a single coal block); its area lies far outside the world border, so it never
generates, and the tests place it by command.
generates, and the tests place it by command. Each tier with "showcase" also gets "<tier>_showcase", a full
radius-2 vein in the same place-only area, which tools/make_world.py places by hand near the zone's sample point.
* global.json: regenerators can't be broken by players (allow_breaking false), so nobody can remove a
vein for good; explosions don't destroy veins.
* vein_locator.json: the Vein Locator from a compass and a copper ingot (mid-game) instead of netherite.
It also writes world/vein-sources.json, the veins as item sources for the field guide (tools/fieldguide/build.py
reads it by default): what each tier's blocks drop and in which zone.
Re-run after changing the zone plan or the grid (tools/zone_layout.py) and commit the result.
Usage: tools/zone_ores.py
@@ -30,6 +34,17 @@ OUT = ROOT / "pack/config/regenerating_ore_veins"
LAYOUT = ROOT / "build/zone-layout.json"
BOTTOM, TOP = -64, 320
SELFTEST_AREA = "selftest_nowhere"
SOURCES = ROOT / "world/vein-sources.json"
# What an ore block drops, where it isn't the block itself or "<name>_ore" → "<name>".
DROPS = {"iron": "raw_iron", "copper": "raw_copper", "gold": "raw_gold", "lapis": "lapis_lazuli",
"nether_quartz": "quartz", "amethyst_block": "amethyst_block", "budding_amethyst": "amethyst_shard"}
def drop_of(block):
namespace, name = block.split(":")
base = name.removeprefix("deepslate_").removeprefix("dripstone_").removeprefix("terracotta_")
base = base.removesuffix("_ore") if base.endswith("_ore") else base
return f"{namespace}:{DROPS.get(base, base)}"
def rectangles(mask, size):
@@ -123,6 +138,10 @@ def main():
else:
sys.exit(f"ore tier {tier}: unknown zone {zone}")
low, high = spec["y"]
if spec.get("showcase"):
blocks = [(spec["stone"], 1)] if spec.get("stone") else [tuple(b) for b in spec["blocks"]]
showcase = vein(f"{tier}_showcase", blocks, spec, defaults, (0, 0), {"area_whitelist": [SELFTEST_AREA]})
veins.append({**showcase, "min_radius": 2, "max_radius": 2, "fill_factor": 0.8})
if "blocks" in spec:
veins.append(vein(tier, spec["blocks"], spec, defaults, (low, high), where))
continue
@@ -158,6 +177,16 @@ def main():
"durability": 2,
"stack_size": 64,
}, indent=2) + "\n")
names = {z["id"]: z["name"] for z in plan["zones"] + plan["caves"]}
sources = []
for tier, spec in plan["ores"].items():
blocks = [b for b, _ in spec.get("blocks", [])] + [spec[k] for k in ("stone", "deepslate") if spec.get(k)]
for item in dict.fromkeys(drop_of(b) for b in blocks):
sources.append({"item": item, "how": f"Regenerating {tier.replace('_', ' ')} vein in {names[spec['zone']]}",
"kind": "ore vein", "needs": []})
SOURCES.write_text(json.dumps({
"_comment": "Generated by tools/zone_ores.py from world/zones.json; extra item sources for the field guide.",
"sources": sources}, indent=1) + "\n")
per_zone = {}
for tier, spec in plan["ores"].items():
per_zone.setdefault(spec["zone"], []).append(tier)
+137
View File
@@ -0,0 +1,137 @@
{
"_comment": "Generated by tools/zone_ores.py from world/zones.json; extra item sources for the field guide.",
"sources": [
{
"item": "minecraft:coal",
"how": "Regenerating coal vein in Button Isle",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:raw_copper",
"how": "Regenerating copper vein in Southwold",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:raw_iron",
"how": "Regenerating iron vein in Westmarch",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:redstone",
"how": "Regenerating redstone vein in Verdant Jungle",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:lapis_lazuli",
"how": "Regenerating lapis vein in Highland Meadows",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:raw_gold",
"how": "Regenerating gold vein in Sunscorch",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:emerald",
"how": "Regenerating emerald vein in Frostpeak Range",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:amethyst_block",
"how": "Regenerating amethyst vein in Dripstone Depths",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:amethyst_shard",
"how": "Regenerating amethyst vein in Dripstone Depths",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:diamond",
"how": "Regenerating diamond vein in Deep Dark",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:quartz",
"how": "Regenerating quartz vein in Basalt Furnace",
"kind": "ore vein",
"needs": []
},
{
"item": "minecraft:ancient_debris",
"how": "Regenerating netherite vein in Basalt Furnace",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:thunder_stone",
"how": "Regenerating thunder stone vein in Westmarch",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:shiny_stone",
"how": "Regenerating shiny stone vein in Lush Caves",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:leaf_stone",
"how": "Regenerating leaf stone vein in Verdant Jungle",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:water_stone",
"how": "Regenerating water stone vein in Mangrove Mire",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:moon_stone",
"how": "Regenerating moon stone vein in Dripstone Depths",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:sun_stone",
"how": "Regenerating sun stone vein in Highland Meadows",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:fire_stone",
"how": "Regenerating fire stone vein in Sunscorch",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:ice_stone",
"how": "Regenerating ice stone vein in Frostpeak Range",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:dawn_stone",
"how": "Regenerating dawn stone vein in Frostpeak Range",
"kind": "ore vein",
"needs": []
},
{
"item": "cobblemon:dusk_stone",
"how": "Regenerating dusk stone vein in Deep Dark",
"kind": "ore vein",
"needs": []
}
]
}
+13 -13
View File
@@ -1,5 +1,5 @@
{
"_comment": "Zone plan for Phase 3 (model approved by Adrian 2026-10-29; levels are placeholders, see docs/balance.md). tools/zone_layout.py assigns each surface cell of the island to the first zone whose rule matches, in this order, and renders build/zone-map.png. Rules: 'within' = distance from 0,0 in blocks; 'biomes' = cells of these biomes, clusters smaller than min_cells dropped, plus 'absorb' = cells of other biomes within that many blocks of the cluster; 'region' = what is left, by half-plane (x/z bounds in blocks); 'water' = sea cells of these biomes. Biomes in 'inherit' (rivers) take the zone of the land around them. Cave zones follow the cave biome everywhere under the island and are not drawn. 'lines' = how many evolution lines tools/zone_spawns.py aims to give the zone (scaled to the lines available); 'species' pins a line to a zone by hand. 'guardian': the zone's Alpha guardian (tools/zone_spawns.py picks the strongest Pokémon spawning in the zone unless 'species' is given, at the band's top level + 5) and its drops, which help with the next zone; it stands at the zone's sample point and returns guardian_respawn_hours after it is beaten (Adrian, 2026-10-29: fixed spots, 5 hours). 'ores': Phase 4 ore tiers for Regenerating Ore Veins (tools/zone_ores.py writes the mod's config from them). Each tier has veins in exactly one zone, higher tiers in higher zones; Cobblemon's evolution stones are tiers too, since their natural ores are off. 'stone'/'deepslate' split a tier into an upper vein (y >= 0) and a lower one; 'blocks' is a weighted list for one vein. 'radius' in blocks, 'y' range, 'spacing' in chunks between candidate chunks, 'regen_minutes' of real time, plus 'jitter' (share of the interval), 'fill' and 'attempts' from 'ore_defaults'. 'showcase': the template gets one hand-placed vein of the tier at its zone's sample point. 'level_pressure': a Pokémon more than grace_levels above the band of the zone its trainer stands in gets per_level less experience per extra level, down to minimum (Exp. Candy and commands excepted).",
"_comment": "Zone plan for Phase 3 (model approved by Adrian 2026-10-29; levels are placeholders, see docs/balance.md). tools/zone_layout.py assigns each surface cell of the island to the first zone whose rule matches, in this order, and renders build/zone-map.png. Rules: 'within' = distance from 0,0 in blocks; 'biomes' = cells of these biomes, clusters smaller than min_cells dropped, plus 'absorb' = cells of other biomes within that many blocks of the cluster; 'region' = what is left, by half-plane (x/z bounds in blocks); 'water' = sea cells of these biomes. Biomes in 'inherit' (rivers) take the zone of the land around them. Cave zones follow the cave biome everywhere under the island and are not drawn. 'lines' = how many evolution lines tools/zone_spawns.py aims to give the zone (scaled to the lines available); 'species' pins a line to a zone by hand. 'guardian': the zone's Alpha guardian (tools/zone_spawns.py picks the strongest Pokémon spawning in the zone unless 'species' is given, at the band's top level + 5) and its drops, which help with the next zone; it stands at the zone's sample point and returns guardian_respawn_hours after it is beaten (Adrian, 2026-10-29: fixed spots, 5 hours). 'ores': Phase 4 ore tiers for Regenerating Ore Veins (tools/zone_ores.py writes the mod's config from them). Each tier has veins in exactly one zone, higher tiers in higher zones; Cobblemon's evolution stones are tiers too, since their natural ores are off. 'stone'/'deepslate' split a tier into an upper vein (y >= 0) and a lower one; 'blocks' is a weighted list for one vein. 'radius' in blocks, 'y' range, 'spacing' in chunks between candidate chunks, 'regen_minutes' of real time, plus 'jitter' (share of the interval), 'fill' and 'attempts' from 'ore_defaults'. Cave tiers' 'y' follows where their biome lies (the biome preview: Deep Dark mostly below y -24, the other three between 0 and 40), and they get more 'attempts', since each try lands at a random height. 'showcase': the template gets one hand-placed vein of the tier near its zone's sample point (vein '<tier>_showcase': radius 2, never generates by itself). 'level_pressure': a Pokémon more than grace_levels above the band of the zone its trainer stands in gets per_level less experience per extra level, down to minimum (Exp. Candy and commands excepted).",
"min_cells": 6,
"inherit": ["minecraft:river"],
"guardian_respawn_hours": 5,
@@ -11,22 +11,22 @@
"iron": {"zone": "westmarch", "stone": "minecraft:iron_ore", "deepslate": "minecraft:deepslate_iron_ore", "radius": [1, 2], "y": [-48, 90], "spacing": 5, "regen_minutes": 40, "attempts": 2, "showcase": true},
"redstone": {"zone": "jungle", "stone": "minecraft:redstone_ore", "deepslate": "minecraft:deepslate_redstone_ore", "radius": [1, 2], "y": [-56, 60], "spacing": 6, "regen_minutes": 45, "showcase": true},
"lapis": {"zone": "highlands", "stone": "minecraft:lapis_ore", "deepslate": "minecraft:deepslate_lapis_ore", "radius": [1, 2], "y": [-56, 80], "spacing": 6, "regen_minutes": 45, "showcase": true},
"gold": {"zone": "sunscorch", "stone": "minecraft:gold_ore", "deepslate": "minecraft:deepslate_gold_ore", "radius": [1, 2], "y": [-48, 120], "spacing": 6, "regen_minutes": 60, "showcase": true},
"emerald": {"zone": "frostpeak", "stone": "minecraft:emerald_ore", "deepslate": "minecraft:deepslate_emerald_ore", "radius": [1, 1], "y": [-16, 320], "spacing": 7, "regen_minutes": 75, "showcase": true},
"amethyst": {"zone": "dripstone", "blocks": [["minecraft:amethyst_block", 3], ["minecraft:budding_amethyst", 1]], "radius": [1, 1], "y": [-64, 64], "spacing": 8, "regen_minutes": 120},
"diamond": {"zone": "deep_dark", "deepslate": "minecraft:deepslate_diamond_ore", "radius": [1, 1], "y": [-64, 0], "spacing": 7, "regen_minutes": 90},
"quartz": {"zone": "basalt", "blocks": [["minecraft:nether_quartz_ore", 1]], "radius": [1, 2], "y": [-64, 64], "spacing": 6, "regen_minutes": 60},
"netherite": {"zone": "basalt", "blocks": [["minecraft:ancient_debris", 1]], "radius": [0, 1], "y": [-64, 32], "spacing": 10, "regen_minutes": 180},
"gold": {"zone": "sunscorch", "stone": "minecraft:gold_ore", "deepslate": "minecraft:deepslate_gold_ore", "radius": [1, 2], "y": [-48, 120], "spacing": 5, "regen_minutes": 60, "showcase": true, "attempts": 2},
"emerald": {"zone": "frostpeak", "stone": "minecraft:emerald_ore", "deepslate": "minecraft:deepslate_emerald_ore", "radius": [1, 1], "y": [-16, 320], "spacing": 6, "regen_minutes": 75, "showcase": true, "attempts": 2},
"amethyst": {"zone": "dripstone", "blocks": [["minecraft:amethyst_block", 3], ["minecraft:budding_amethyst", 1]], "radius": [1, 1], "y": [0, 40], "spacing": 10, "regen_minutes": 120, "attempts": 4},
"diamond": {"zone": "deep_dark", "deepslate": "minecraft:deepslate_diamond_ore", "radius": [1, 1], "y": [-64, -24], "spacing": 10, "regen_minutes": 90, "attempts": 3},
"quartz": {"zone": "basalt", "blocks": [["minecraft:nether_quartz_ore", 1]], "radius": [1, 2], "y": [0, 40], "spacing": 8, "regen_minutes": 60, "attempts": 3},
"netherite": {"zone": "basalt", "blocks": [["minecraft:ancient_debris", 1]], "radius": [0, 1], "y": [0, 40], "spacing": 14, "regen_minutes": 180, "attempts": 2},
"thunder_stone": {"zone": "westmarch", "stone": "cobblemon:thunder_stone_ore", "deepslate": "cobblemon:deepslate_thunder_stone_ore", "radius": [0, 1], "y": [-48, 100], "spacing": 8, "regen_minutes": 60},
"shiny_stone": {"zone": "lush_caves", "stone": "cobblemon:shiny_stone_ore", "deepslate": "cobblemon:deepslate_shiny_stone_ore", "radius": [0, 1], "y": [-64, 64], "spacing": 8, "regen_minutes": 60},
"shiny_stone": {"zone": "lush_caves", "stone": "cobblemon:shiny_stone_ore", "deepslate": "cobblemon:deepslate_shiny_stone_ore", "radius": [0, 1], "y": [-16, 40], "spacing": 10, "regen_minutes": 60, "attempts": 4},
"leaf_stone": {"zone": "jungle", "stone": "cobblemon:leaf_stone_ore", "deepslate": "cobblemon:deepslate_leaf_stone_ore", "radius": [0, 1], "y": [-48, 100], "spacing": 8, "regen_minutes": 60},
"water_stone": {"zone": "mire", "stone": "cobblemon:water_stone_ore", "deepslate": "cobblemon:deepslate_water_stone_ore", "radius": [0, 1], "y": [-48, 100], "spacing": 8, "regen_minutes": 60, "showcase": true},
"moon_stone": {"zone": "dripstone", "blocks": [["cobblemon:dripstone_moon_stone_ore", 1], ["cobblemon:moon_stone_ore", 1], ["cobblemon:deepslate_moon_stone_ore", 1]], "radius": [0, 1], "y": [-64, 64], "spacing": 8, "regen_minutes": 60},
"moon_stone": {"zone": "dripstone", "blocks": [["cobblemon:dripstone_moon_stone_ore", 1], ["cobblemon:moon_stone_ore", 1], ["cobblemon:deepslate_moon_stone_ore", 1]], "radius": [0, 1], "y": [0, 40], "spacing": 10, "regen_minutes": 60, "attempts": 4},
"sun_stone": {"zone": "highlands", "stone": "cobblemon:sun_stone_ore", "deepslate": "cobblemon:deepslate_sun_stone_ore", "radius": [0, 1], "y": [-48, 100], "spacing": 8, "regen_minutes": 60},
"fire_stone": {"zone": "sunscorch", "stone": "cobblemon:fire_stone_ore", "deepslate": "cobblemon:deepslate_fire_stone_ore", "radius": [0, 1], "y": [-48, 120], "spacing": 8, "regen_minutes": 60},
"ice_stone": {"zone": "frostpeak", "stone": "cobblemon:ice_stone_ore", "deepslate": "cobblemon:deepslate_ice_stone_ore", "radius": [0, 1], "y": [-16, 320], "spacing": 8, "regen_minutes": 60},
"dawn_stone": {"zone": "frostpeak", "stone": "cobblemon:dawn_stone_ore", "deepslate": "cobblemon:deepslate_dawn_stone_ore", "radius": [0, 1], "y": [-16, 320], "spacing": 9, "regen_minutes": 75},
"dusk_stone": {"zone": "deep_dark", "deepslate": "cobblemon:deepslate_dusk_stone_ore", "radius": [0, 1], "y": [-64, 0], "spacing": 9, "regen_minutes": 75}
"fire_stone": {"zone": "sunscorch", "stone": "cobblemon:fire_stone_ore", "deepslate": "cobblemon:deepslate_fire_stone_ore", "radius": [0, 1], "y": [-48, 120], "spacing": 6, "regen_minutes": 60, "attempts": 2},
"ice_stone": {"zone": "frostpeak", "stone": "cobblemon:ice_stone_ore", "deepslate": "cobblemon:deepslate_ice_stone_ore", "radius": [0, 1], "y": [-16, 320], "spacing": 6, "regen_minutes": 60, "attempts": 2},
"dawn_stone": {"zone": "frostpeak", "stone": "cobblemon:dawn_stone_ore", "deepslate": "cobblemon:deepslate_dawn_stone_ore", "radius": [0, 1], "y": [-16, 320], "spacing": 7, "regen_minutes": 75, "attempts": 2},
"dusk_stone": {"zone": "deep_dark", "deepslate": "cobblemon:deepslate_dusk_stone_ore", "radius": [0, 1], "y": [-64, -24], "spacing": 12, "regen_minutes": 75, "attempts": 3}
},
"species": {"durant": "basalt", "torkoal": "basalt", "heatmor": "basalt"},
"zones": [