Phase 5: breeding with Cobbreeding, Ditto a rare Deep Dark find

Adrian (2026-10-31): add Cobbreeding without a gate; only Ditto should
be rare, in an endgame area or gated behind something else.

- Cobbreeding 2.4.1 (Modrinth only) and Cloth Config (client) in the
  pack; Cobblebase's hatchery takes Cobbreeding's eggs.
- Ditto moved from Button Isle to the Deep Dark with both of Cobblemon's
  entries (rare in slime chunks, ultra-rare elsewhere): zone_spawns.py
  pins take {"zone", "all_entries"}; Deep Dark target +1, Button Isle -1
  so no other line moved; Southwold and Frostpeak guardians pinned (they
  tie on base stats and flipped between runs).
- HMs' Trainer Ditto is made uncatchable; it still trades.
- check_deps.py skips other-side dependencies; Cobbreeding's harmless
  client-mixin log line allowlisted.
- Self-tests cobbreeding_eggs_fit_the_hatchery, trainer_ditto_cant_be_caught;
  docs, balance table, Phase 5 checklist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-31 19:13:55 +01:00
1 parent 5b304025c6
commit 5cae9252c3
20 files changed
+274 -148

No files matched your search

+8 -2
View File
@@ -23,7 +23,9 @@ datapacks/core/data/cobblesurvival/spawn_pool_world/<zone>.json:
doesn't spawn there. If no stage fits, the closest one spawns across the whole band. Every
stage that reaches the band spawns up to its top (Adrian, 2026-10-31; Cobblemon's own ranges
stop where the next stage takes over, which left e.g. Dusclops at Lv 45–46 in the Deep Dark).
3. world/zones.json → "species" pins a line to a zone by hand: {"pikachu": "southwold"}.
3. world/zones.json → "species" pins a line to a zone by hand: {"pikachu": "southwold"}. The long form
{"ditto": {"zone": "deep_dark", "all_entries": true}} also keeps all of the line's entries when no stage
fits the band (otherwise the closest stage brings one entry).
4. In 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 (there's no sky or day underground).
5. Strong flyers (STRONG_FLYER_*) only spawn in zones whose band starts at HIGH_ZONE_LEVEL or more.
@@ -180,7 +182,9 @@ def main():
continue
lines[line_root(member, species)].append((entry, set(s["biomes"]), member, s["level"]))
pinned = {f"cobblemon:{k}" if ":" not in k else k: v for k, v in plan.get("species", {}).items()}
pins = {f"cobblemon:{k}" if ":" not in k else k: v for k, v in plan.get("species", {}).items()}
pinned = {root: pin["zone"] if isinstance(pin, dict) else pin for root, pin in pins.items()}
all_entries = {root for root, pin in pins.items() if isinstance(pin, dict) and pin.get("all_entries")}
flying_lines = {root for root in lines if root in strong_flyers}
def allowed(root, zid):
@@ -269,6 +273,8 @@ def main():
# No stage reaches the band: the closest stage spawns across all of it.
e, b, m, lv = min(usable, key=lambda u: min(abs(u[3][0] - hi), abs(u[3][1] - lo)))
fitting = [(e, m, lo, hi)]
if root in all_entries:
fitting = [(ue, m, lo, hi) for ue, _, um, ulv in usable if um == m and ulv == lv]
seen = set()
for entry, member, a, b in fitting:
spawn = copy.deepcopy(entry)