Phase 4 play-test fixes: deep caves, fuller cave spawns, strays, shared loot

From Adrian's play-test (2026-10-30):
- The Deep Dark no longer fills the deepslate layer: world/biomes.json
  splits it by temperature (Deep Dark under cold and temperate land,
  basalt deltas under the hottest, ordinary caves between); at y -52 it
  drops from 30 % to 14 % of the land, basalt 7 %.
- Cave zones fill up to their targets with lines whose primary type fits
  the cave; top stages spawn up to the band's top (Deep Dark Lv 60, Basalt
  70); no time-of-day conditions underground.
- Wild Pokemon more than 10 levels above the band of the zone they
  wander into despawn (zone/Wanderers.kt).
- Loot is shared: all players in one scoreboard team, Lootr team_loot.
- Basalt ore nodes reach the deep basalt.
Self-tests strays_despawn and loot_is_shared; the catching rules from the
previous commit are now tested too. Template rebuilt (world check passed),
island quick check passed (36 self-tests and the restart test).
Shoulder Pokemon noted for Phase 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-31 02:01:41 +01:00
1 parent 6361636da7
commit d49684a2eb
40 files changed
+8212 -9412

No files matched your search

+11 -5
View File
@@ -26,6 +26,7 @@ The roadmap (design pillars, phases, open decisions) is the source of truth for
| The biome list is enforced by remapping vanilla's overworld biome table (from Minecraft's data generator) onto the list, written into the world type by `tools/biome_layout.py` | Keeps vanilla's terrain–biome fit (peaks on peaks, swamps in lowlands) while only listed biomes can appear. Pure data. WorldGen Editor's own climate/exclusion options were rejected: they replace cave biomes with surface fallbacks such as snowy plains, and leak unlisted biomes |
| "Mountain edge" → `windswept_hills` (with snowy slopes and stony shore folded in) | Mountain Edge was removed in 1.18; windswept hills is its successor. **Flagged** in case another biome was meant |
| Basalt deltas is an overworld cave biome under the hottest, driest land (where desert and badlands are), at cave depth like lush and dripstone caves | Adrian's request. It keeps its own features (basalt columns, magma, lava deltas) and particles; its nether ores are removed with the rest |
| The Deep Dark no longer fills the deepslate layer (Adrian, 2026-10-30: "too much"; part of it should become basalt deltas). Vanilla puts it at depth 1.1 wherever erosion is low, at any temperature; `world/biomes.json` → `split` cuts it by the temperature of the land above: up to −0.1 Deep Dark, from 0.4 basalt deltas, in between ordinary caves of the land above | Biome preview at y −52, share of land: Deep Dark 30 % → 14 %, basalt deltas 0 → 7 %, ordinary caves 9 %; at y −30 Deep Dark 18 % → 7 %. The deep basalt is part of the Basalt Furnace (Lv 55–70), so the deepest caves reach Lv 70 under hot land. The gaps between the pieces must be wide: Minecraft picks the nearest biome entry, and the land biome above is only 0.1 away in depth, so a narrow gap goes to the neighbouring piece |
| No Nether: the world type `cobblesurvival:island` defines only the overworld and the End | Adrian's request. Portals can still be lit but lead nowhere. The smoke test checks that `minecraft:the_nether` is an unknown dimension |
| Island shaped like a Poké Ball (Adrian, 2026-10-28): a round island cut into top and bottom halves by a channel across the middle, with a ring channel around a round centre island where the spawn is. Written by `tools/pokeball_preset.py` (ball r 1,500, band 160, button r 280, ring 120 — placeholders) | WorldGen Editor makes the round island; two flat-ended ocean entries cut the band and 36 overlapping ocean circles cut the ring. Entries have no climate or exclusions; biomes come from the remapped table |
| The seed is chosen by `tools/seed_search.py`, which scores many seeds with the op-only dev command `/cobblesurvival biomepreview` (samples the generator without generating chunks) | With vanilla climate noise, which biomes land on a 1,500-block island depends on the seed. The search wants every listed biome at a useful share, few large patches, a gentle start area and all four cave biomes |
@@ -58,7 +59,7 @@ The roadmap (design pillars, phases, open decisions) is the source of truth for
| No healing while sleeping: Cobblemon `healPercent` 0 | Cobblemon only uses `healPercent`/`healTimer` while the player sleeps |
| Healing Machines are expensive (roadmap): a dearer recipe (gold, iron, a Max Revive and a diamond) and a four times slower recharge; values in `docs/balance.md` | With loot chests handing out ingots (Adrian, 2026-10-29), Cobblemon's copper-and-iron recipe would be cheap early on. The recipe is replaced by KubeJS under the id `cobblesurvival:healing_machine` |
| Fight or Flight Reborn and TP-Pastures installed with default settings | Tuning comes with the zones (Phase 3) and pastures (Phase 4) |
| Chest loot keeps its ore and ingots; every loot container refills with a new roll 1 hour after it was first opened (Adrian, 2026-10-29). Tiering loot by structure/biome comes later (lower priority) | Done with Lootr (`config/lootr-common.toml`: `refresh_all`, `refresh_value` 72,000 ticks of game time). Lootr also makes loot per player. This changes the roadmap's Phase 2 item "remove loot tables that hand out ore or ingots": chests are a second, renewable ore source next to the veins (pillar 3) |
| Chest loot keeps its ore and ingots; every loot container refills with a new roll 1 hour after it was first opened (Adrian, 2026-10-29). Tiering loot by structure/biome comes later (lower priority) | Done with Lootr (`config/lootr-common.toml`: `refresh_all`, `refresh_value` 72,000 ticks of game time). Loot is shared by all players (Adrian, 2026-10-30): every player joins the scoreboard team `islanders` (`world/SharedLoot.kt`) and Lootr's `team_loot` is on, so a container has one inventory for everybody. Cobblemon's gilded chests (Gimmighoul's hiding spots) aren't Lootr containers: their loot is rolled once, shared, and doesn't come back. This changes the roadmap's Phase 2 item "remove loot tables that hand out ore or ingots": chests are a second, renewable ore source next to the veins (pillar 3) |
| Lootr converts a vanilla loot chest once the 5×5 chunks around it are loaded, i.e. when a player is near, not during pregeneration | So the template keeps vanilla loot chests until then. `tools/quick_check.py` force-loads the area around a sampled village and checks that its chests became Lootr chests |
| Matthiesen Core's usage statistics are off by default | A pack shouldn't send data for its players without asking; players can switch it on in `config/matthiesen_core/metrics.properties` |
@@ -84,8 +85,8 @@ A zone decides **which Pokémon spawn** and **at what levels**: Cobblemon's own
| Deep Sea | ring and band channels, outer sea | deep ocean | 30–50 | none | Heart Scale-type rarities | Lapras or Wailord, Lv 55 |
| Lush Caves | under the whole island | lush caves | 12–28 | none | glow berries, mushrooms (Paras) | none |
| Dripstone Depths | under the whole island | dripstone caves | 22–38 | none | Dragon Fang (Bagon, Gible) | none |
| Deep Dark | under the whole island | deep dark | 45–60 | darkness (vanilla sculk; no Warden) | | Sableye or Spiritomb, Lv 62 |
| Basalt Furnace | under the whole island | basalt deltas | 55–70 | heat (Cold Sweat) | **raw iron** (Durant), coal (Torkoal), blaze powder (Heatmor) | Heatran-like boss later (Phase 7) |
| Deep Dark | under the cold and temperate land, deep (since 2026-10-30) | deep dark | 45–60 | darkness (vanilla sculk; no Warden) | | Sableye or Spiritomb, Lv 62 |
| Basalt Furnace | under the hottest land, at cave depth and (since 2026-10-30) down to the bottom | basalt deltas | 55–70 | heat (Cold Sweat) | **raw iron** (Durant), coal (Torkoal), blaze powder (Heatmor) | Heatran-like boss later (Phase 7) |
Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jungle → Mire or Highlands → Sunscorch (heat) → Frostpeak (cold) → the deep caves.
@@ -104,8 +105,9 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
**How zones are built** (Phase 3, step 2):
- `tools/zone_layout.py` writes the zone grid to `datapacks/core/data/cobblesurvival/zones/island.json` (24-block cells; caves by cave biome). The companion mod loads it (`zone/Zones.kt`) and adds the spawn-condition field `"zone"`/`"zones"` to every Cobblemon spawn condition. `/cobblesurvival zone` (operators) names the zone you stand in.
- Cobblemon's own spawn files are switched off by a filter in `datapacks/core/pack.mcmeta`. `tools/zone_spawns.py` writes one spawn pool per zone (`datapacks/core/data/cobblesurvival/spawn_pool_world/<zone>.json`) from Cobblemon's spawn data: every evolution line that can spawn on the island gets one home zone (none is lost; legendaries, mythicals, Ultra Beasts and Paradox Pokémon stay out), and its levels are clamped into the zone's band, which picks the evolution stages. Placement weighs how much of the zone is the line's habitat, how much of the line's range the zone covers, and the line's strength (base-stat total of its strongest form) against the zone's band. Lines that Cobblemon lets spawn nearly everywhere are shared out over the land zones by strength. The result per zone is in `docs/zone-species.md`; `world/zones.json` → `species` pins a line by hand.
- Cave zones: sky-light minimums, "can see sky" and the "natural" ground preset are dropped from their entries; otherwise the Deep Dark (fed by Cobblemon's surface "spooky" spawns) could never spawn anything, and lush caves' moss floors would barely count.
- Cobblemon's own spawn files are switched off by a filter in `datapacks/core/pack.mcmeta`. `tools/zone_spawns.py` writes one spawn pool per zone (`datapacks/core/data/cobblesurvival/spawn_pool_world/<zone>.json`) from Cobblemon's spawn data: every evolution line that can spawn on the island gets one home zone (none is lost; legendaries, mythicals, Ultra Beasts and Paradox Pokémon stay out), and its levels are clamped into the zone's band, which picks the evolution stages; the line's top stage spawns up to the top of the band (Cobblemon's own ranges stop earlier: the Deep Dark used to top out at Lv 54). Placement weighs how much of the zone is the line's habitat, how much of the line's range the zone covers, and the line's strength (base-stat total of its strongest form) against the zone's band. Lines that Cobblemon lets spawn nearly everywhere first fill the cave zones, which take those whose first stage's primary type fits the cave (`world/zones.json` → caves → `types`; Adrian, 2026-10-30: the deep caves' tables were too small), then are shared out over the land zones by strength. The result per zone is in `docs/zone-species.md`; `world/zones.json` → `species` pins a line by hand.
- Cave zones: every entry spawns in the cave's biome, and sky-light minimums, "can see sky", time of day, excluded biomes and the "natural" ground preset are dropped; otherwise the Deep Dark (fed by Cobblemon's surface "spooky" spawns, many of them night-only) would barely spawn anything, and lush caves' moss floors would barely count.
- Strays (Adrian, 2026-10-30: a Lv 61 from the Basalt Furnace turned up in the Lush Caves): every 5 seconds a wild Pokémon near a player that stands in a zone whose band it tops by more than 10 levels despawns, unless it is in a battle, angry at someone or a guardian (`zone/Wanderers.kt`, `world/zones.json` → `wanderers`). Tested: `strays_despawn`.
- Basalt Furnace got Durant, Torkoal and Heatmor pinned to it: its own lines were all big (Charizard, Turtonator, Centiskorch, …) and Cobblemon only spawns a Pokémon where its body fits, so cramped basalt caves stayed empty.
- Tested: `spawn_pools_are_zoned` (no Cobblemon default spawn is left; every entry has a zone and spawns within its band) and `spawn_survey` (a player at a point deep inside each zone is offered only that zone's spawns, and at least one), both in `tools/quick_check.py`.
@@ -165,6 +167,10 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
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`.
## Notes for Phase 5
- **Shoulder Pokémon** (Adrian, 2026-10-30): Cobblemon lets a player carry a small Pokémon on their shoulder (96 species are `shoulderMountable`: Pidgey, Pikachu, Eevee, Zubat, Squirtle, ...). It has a shoulder-effect system with one type, `potion_effect` (effect, amplifier, particles, icon), but no species uses it in 1.8. Party passives can start there, as data: species additions giving shoulder Pokémon an effect while carried (e.g. Pidgey slow falling, Zubat night vision, a Fire type warmth against Frostpeak's cold), maybe gated behind progression like Cobblebase's skills. To check first: that species additions can set `shoulderEffects`, and how the effect behaves when the Pokémon faints or goes back in its ball.
## Open decisions for Adrian (proceeding with the default, flagged)
| Decision | Default used for now |