WIP: ore nodes, catching rules, bee nest fix, smaller Deep Dark

Done and checked: surface and cave-floor ore nodes (companion mod
ore/OreNodes.kt), bigger and rarer underground veins; template with nodes
passed the world check and the island quick check (node self-tests).

Built, not yet tested: catching rules (catch rate falls with the level
gap to the trainer's strongest Pokemon, failed catch enrages, strong wild
Pokemon hunt weaker trainers; catching/, Fight or Flight config), bee
nests emptied when their bee is turned away.

In progress: the Deep Dark no longer fills the deepslate layer (split by
temperature: cold = Deep Dark, hot = basalt deltas, warm = ordinary caves;
world/biomes.json), zone layout regenerated; cave zone types added to
world/zones.json but tools/zone_spawns.py doesn't use them yet; template
not rebuilt for the new caves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-30 15:44:17 +01:00
1 parent 362d06aa4b
commit 6361636da7
29 files changed
+1733 -357

No files matched your search

+5 -1
View File
@@ -32,7 +32,8 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue
| 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 | Fine for now (Adrian, 2026-10-30) | `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 | Fine for now (Adrian, 2026-10-30) | `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`) | Fine for now (Adrian, 2026-10-30) | `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` |
| Ore nodes | chance per chunk of the zone — surface: coal 50 %, copper 20 %, iron 20 %, redstone 20 %, lapis 15 %, gold 30 %, emerald 15 %, thunder stone 3 %, leaf stone 4 %, water stone 4 %, sun stone 2 %, fire stone 8 %, ice stone 6 %, dawn stone 4 %; cave floor (8 columns searched): amethyst 50 %, diamond 15 %, quartz 50 %, netherite 6 %, shiny stone 15 %, moon stone 25 %, dusk stone 10 %. Radius 0–1 (evolution stones and netherite one block), 80 % filled | Placeholder (Adrian, 2026-10-30: small on the surface) | `world/zones.json` → `ores` → `nodes` | |
| Underground veins (surface tiers) | radius 2–4 (stones 1–2), spacing 6–11 chunks between candidate chunks, 70 % filled, 1–2 tries per candidate chunk | Placeholder (Adrian, 2026-10-30: larger but harder to find) | `world/zones.json` → `ores` → `veins` | 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 | Fine for now (Adrian, 2026-10-30) | `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) | Fine for now (Adrian, 2026-10-30) | `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 % | Fine for now (Adrian, 2026-10-30) | `datapacks/core/data/cobblesurvival/species_additions/` | Every drop and what consumes it: `docs/pokemon-drops.md` (`tools/drop_audit.py`) |
@@ -40,6 +41,9 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue
| Power Block gate | after the Verdant Jungle guardian | Placeholder | same file, `blocks` | Recipe: Poke Power's own (iron blocks, redstone blocks, Electirizer) |
| Poke Power output | 50 FE/t per Pokémon level, block stores 120,000 FE, 16,000 FE/t out; cable 32,000 / 16,000 | The mod's defaults | `pack/config/poke_power/server.toml` | Nothing uses the energy before Phase 6 |
| Cobblebase jobs | the mod's defaults (finder cooldown 240 s, passive XP 5 % a minute with a Mentor, recruiter rates, buffs) | The mod's defaults | `pack/config/cobblebase.json` (skill cooldowns in its own skill data) | Tune after play-testing |
| Catch rate against stronger Pokémon | full up to the trainer's strongest party level, then falling linearly to 2 % of the normal rate at +20 levels and beyond | Placeholder (Adrian, 2026-10-30: 20+ levels higher very improbable) | `datapacks/core/data/cobblesurvival/catching/rules.json` → `catch_rate` | E.g. +10 levels: about half the normal rate |
| Failed catch | the Pokémon attacks the thrower; while it has a target, thrown balls don't catch it | Decided (Adrian, 2026-10-30) | same file, `failed_catch_enrages`; `config/fightorflight.json5` | Pokémon below Lv 5 never fight back (Fight or Flight `minimum_attack_level`) |
| Hostile to weaker trainers | a wild Pokémon above a player's strongest party Pokémon attacks that player within 16 blocks | Decided (Adrian, 2026-10-30); range placeholder | same file, `hostile_when_stronger`, `hostile_range` | |
| 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 |
+3 -2
View File
@@ -3,7 +3,7 @@
## 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.
- **Ore nodes** (Adrian, 2026-10-30): small nodes on the surface, larger veins underground that are harder to find, and the cave zones' ores as nodes on the cave floor. Automated: `surface_nodes_lie_in_the_ground`, `cave_nodes_lie_on_the_cave_floor`, and the world report (every tier has nodes).
- **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)
@@ -11,7 +11,8 @@
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).
- [ ] Walk around Button Isle: small coal nodes lie in the grass. Mine one: it turns into a regenerator block, and right-clicking it says how long until it grows back (20 minutes of real time for coal).
- [ ] Fly through a cave zone in spectator mode: its nodes sit on the cave floor (amethyst in the Dripstone Depths, diamonds in the Deep Dark, ...), not inside the rock.
- [ ] 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).
+18 -6
View File
@@ -132,15 +132,17 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
**Adrian's answers (2026-10-30):** Cobblebase's skills look fun and stay in, gated behind progression; power comes from an existing mod, also gated (Cobblemon Poke Power); evolution stones as ores are fine for now; the balance values are fine for now and stay configurable, to tweak later.
**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`:
**Ore nodes and veins.** Ore only comes from [Regenerating Ore Veins](https://www.curseforge.com/minecraft/mc-mods/regenerating-ore-veins) (plus chest loot): a mined ore block turns into a regenerator and grows back after its time, which counts in real time, unlike the guardians' game time. Each ore tier lives in exactly one zone, higher tiers in higher zones (table in `docs/balance.md`). Adrian (2026-10-30): ore shows up mainly as **small nodes on the surface**, the **larger veins underground are harder to find**, and the cave zones' ores are **nodes on the cave floor, not in the walls**. `tools/zone_ores.py` writes the vein mod's config (`pack/config/regenerating_ore_veins/`) and the node table 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.
- **Surface nodes** (every surface tier): 1–5 ore blocks lying in natural ground (grass, dirt, sand, stone, snow, ...; tag `cobblesurvival:ore_node_ground`), at most one block standing out, never in water or under leaves, a given chance per chunk of the tier's zone. Evolution stones are single blocks and rarer.
- **Cave nodes** (Lush Caves, Dripstone Depths, Deep Dark, Basalt Furnace): a lump on a cave floor in the tier's cave biome, at the depths where that biome lies (the Deep Dark mostly below y −24, the others between 0 and 40). Cave tiers have no veins inside the rock.
- The companion mod places the nodes (`ore/OreNodes.kt`, table `datapacks/core/data/cobblesurvival/ore_nodes/island.json`) in every new overworld chunk, through the vein mod's own placement, so they are veins like any other and grow back.
- **Underground veins** (surface tiers): larger (radius 2–4) and fewer than the nodes, generated by the vein mod inside the rock under their zone. A surface zone is a set of boxes cut from the zone grid; the mod checks every vein block against them, so no vein block lies outside its zone; cave biomes are zones of their own, which the veins keep out of (the mod checks the biome at a vein's centre, so an edge can reach a little over a cave border). Tiers with an ordinary and a deepslate ore get two veins: the ordinary ore from y 0 up, the deepslate one below.
- **Vein Locator**: attuned in the crafting grid with an ore *block* (needs Silk Touch), it finds the nearest vein or node of exactly that block and throws a signal toward it like an Eye of Ender; 75 % chance to break per use. Attuned to the deepslate ore it only finds the deep half of the veins.
- **Cobblemon's evolution stones are tiers too** (approved for now, 2026-10-30): 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`).
- Both mods fill a new chunk only while it is loaded, a few chunks a tick, and the vein mod 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 has its veins and nodes (`/cobblesurvival veins unfilled` counts what's left), and the world report fails on any chunk without them. On a live server new chunks fill as players load them.
- Checked: the world report (ore only in tracked veins and nodes inside their tier's zone, every tier with nodes and every surface tier with veins, every chunk filled) and the self-tests `surface_nodes_lie_in_the_ground`, `cave_nodes_lie_on_the_cave_floor`, `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`.
@@ -151,6 +153,16 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
- Operators: `/cobblesurvival progress <player>`, `... grant|revoke <player> <zone>`.
- Self-tests: `gates_cover_every_cobblebase_skill` (every skill has a gate, every gate zone has a guardian, every executor is gated), `cobblebase_skills_wait_for_guardians` and `power_block_waits_for_guardian`; `guardian_appears_and_returns` checks that the win counts as progress.
**Catching high-level Pokémon** (Adrian, 2026-10-30). Measured against the trainer's strongest party Pokémon (`catching/Catching.kt`, values in `datapacks/core/data/cobblesurvival/catching/rules.json`):
- The catch rate falls with the level gap: full at the trainer's level, then linearly down to 2 % of the normal rate at 20 levels above and beyond ("20+ levels higher should be very improbable"). Applied to the rate Cobblemon's catch formula uses (its catch-rate event), so balls, status and HP still count.
- A failed catch angers the Pokémon: it attacks the thrower instead of fleeing.
- A wild Pokémon above the strongest Pokémon in a nearby player's party (16 blocks) is hostile to that player.
- The fighting is [Fight or Flight Reborn](https://modrinth.com/mod/cobblemon-fight-or-flight-reborn)'s: an angry Pokémon gets the aspect `cobblesurvival_enraged`, which the pack's `config/fightorflight.json5` lists in `always_aggro_aspects` (so it fights rather than flees), and its target is set through Fight or Flight's own "caught by" mark, by reflection. While an angry Pokémon has a target, thrown balls don't catch it (Fight or Flight's `aggressive_pokemon_catchable` false, its default): it has to be battled. Pokémon below Lv 5 never fight back (its `minimum_attack_level`).
- Self-tests: `catch_rate_falls_with_level_gap`, `failed_catch_enrages`, `strong_wild_pokemon_hunt_weak_trainers`, `wild_pokemon_ignore_stronger_trainers`.
**Bee nests** (found by Adrian in the Phase 4 world): a nest whose bee the island turns away kept the bee and tried to let it out every tick, with its sound each time. The companion mod now empties such a nest (`world/OnlyPokemon.kt`); honey still comes from Combee and shearing nests that have honey.
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)