Cobblemon Survival Pack: phases 0-2 and Phase 3 zones and hazards

Free NeoForge 1.21.1 modpack on Cobblemon 1.8.4 built with packwiz, plus
the Kotlin companion mod (cobblesurvival) and its built-in data pack.

- Phase 0: packwiz pack with Modrinth/CurseForge cross-links, build and
  export tooling, Prism instance sync, test server with smoke checks.
- Phase 1: Poke Ball shaped island (WorldGen Editor preset, seed isle-26),
  Adrian's biome list, no natural ore, structures without ore or vanilla
  mobs, no Nether portals, world template builder and world report.
- Phase 2: permadeath (CobbleHardcoreMon plus the companion mod's gap
  fixes), Revival Charm, expensive Healing Machine, Lootr refreshing
  loot, in-game self-tests on Minecraft's GameTest framework.
- Phase 3 so far: 14 zones with their own spawn pools and level bands
  (tools/zone_layout.py, tools/zone_spawns.py, "zone" spawn condition),
  Cold Sweat heat and cold as gates with boss-drop insulation recipes,
  spawn survey and hazard self-tests in tools/quick_check.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-29 19:01:21 +01:00
commit 398301f0be
232 files changed
+72665

No files matched your search

+72
View File
@@ -0,0 +1,72 @@
"""Pokédex text override: Cobblemon's description keys with "Found in: …" appended.
The keys are the ones each species JSON lists under "pokedex" (for example
cobblemon.species.eevee.desc, plus form keys such as cobblemon.species.eevee-gmax.desc
for non-battle forms). Values are Cobblemon's own English text from its jar
with one sentence added, written as kubejs/assets/cobblemon/lang/en_us.json,
which KubeJS serves as a resource pack. Language files merge key by key, so
only these keys are overridden.
"""
import json
MAX_PLACES = 4
def suffix(sp):
if sp["wild"] == "available" and sp["locations"]:
natural = [l for l in sp["locations"] if not l.get("special")] or sp["locations"]
locs = sorted(natural, key=lambda l: (min(_rarity(b) for b in l["buckets"]), l["name"]))
parts = [f"{l['name']} (Lv {l['level'][0]}-{l['level'][1]})" for l in locs[:MAX_PLACES]]
more = f" and {len(locs) - MAX_PLACES} more" if len(locs) > MAX_PLACES else ""
return f"Found in: {', '.join(parts)}{more}."
if sp["wild"] == "conditional" and sp["locations"]:
return "Found in: " + ", ".join(l["name"] for l in sp["locations"][:MAX_PLACES]) + " (the End)."
ways = [s["text"] for s in sp["sources"] if s["status"] != "unavailable"]
if ways:
return f"Not wild on this island. {ways[0]}."
return "Cannot be obtained on this island." if sp["implemented"] else ""
def _rarity(bucket):
return {"common": 0, "uncommon": 1, "rare": 2, "ultra-rare": 3, "boss": 4}.get(bucket, 5)
def build(data, lang):
out, missing = {}, []
for sid, sp in data["species"].items():
add = suffix(sp)
if not add:
continue
for key in sp["pokedex_keys"]:
if key not in lang:
missing.append(key)
continue
out[key] = f"{lang[key].rstrip()} {add}"
return dict(sorted(out.items())), missing
README = """# Pokédex "Found in" text (generated, not installed)
`kubejs/assets/cobblemon/lang/en_us.json` overrides {count} of Cobblemon's Pokédex description keys
(`cobblemon.species.<name>.desc` and form keys) with the original English text plus one sentence:
"Found in: Plains (Lv 5-32), …", or how to get the Pokémon if it is not wild on this island.
## Installing (your decision)
1. Copy `kubejs/assets/cobblemon/lang/en_us.json` to `pack/kubejs/assets/cobblemon/lang/en_us.json`
(or to `kubejs/assets/...` in an instance). KubeJS loads `kubejs/assets` as a resource pack on the client.
2. If that file already exists, merge the keys (later keys win; nothing else uses these keys).
3. Restart the client or press F3+T, then open the Pokédex on a Pokémon.
Regenerate after a Cobblemon update or a spawn change: the file holds a copy of Cobblemon's own text.
Other languages keep Cobblemon's text; only en_us is generated.
"""
def write(data, lang, out):
entries, missing = build(data, lang)
dst = out / "kubejs/assets/cobblemon/lang/en_us.json"
dst.parent.mkdir(parents=True, exist_ok=True)
dst.write_text(json.dumps(entries, ensure_ascii=False, indent=2) + "\n")
(out / "kubejs/README.md").write_text(README.format(count=len(entries)))
return len(entries), missing