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>
World template
The island world is generated, not hand-built. This folder holds the recipe. The world itself is a build output (several hundred MB of region files), so it stays out of git.
| File | What it sets |
|---|---|
world.json |
Seed, world type, pregeneration radius, border margin, pinned Chunky download |
biomes.json |
The biome list and how every vanilla biome maps onto it, plus extra entries (basalt deltas as a cave biome) |
../pack/config/worldgen_editor/presets/cobblesurvival_island.json |
The island's outline: a Poké Ball (round island, channel across the middle, ring channel around the centre island). Generated by tools/pokeball_preset.py |
../datapacks/core/data/cobblesurvival/worldgen/world_preset/island.json |
The world type cobblesurvival:island: overworld (island shape + remapped biome table) and the End, no Nether. Generated by tools/biome_layout.py from biomes.json; don't edit by hand |
Building it
python3 tools/biome_layout.py # only after changing biomes.json
python3 tools/seed_search.py # only to pick a new seed (add --apply to write it to world.json)
python3 tools/build.py && python3 tools/make_world.py
seed_search.py previews many seeds without generating chunks (op-only dev command /cobblesurvival biomepreview) and ranks them on biome coverage, patch size, a gentle start area and cave biomes. It writes build/seed-search/candidates.png and report.json.
make_world.py uses the local test server (its eula.txt must already accept the EULA). In one server session it creates the world, pregenerates a circle of pregen_radius with Chunky (the island and a strip of sea; the sea corners inside the square border generate when someone gets there), and puts a square world border border_margin blocks outside the outermost coast. It takes about 6 minutes and writes:
build/world-template/: the world, without player databuild/island-map.png: top-down biome map with zone outlines, border and spawnbuild/island-report.json: ore scan, land bounds, border gaps, biome shares
For checking a change without rebuilding the island, tools/quick_check.py samples a fresh world instead (about 1–2 minutes; structures to sample are listed under quick_check in world.json).
python3 tools/prism_instance.py installs the template into the Prism instance as the save Cobblemon Survival Island. tools/smoke_test.py boots the test server on it.
Same seed, preset and mod versions give the same island. After changing any of them, rebuild the template; existing chunks never change on their own.
Editing the island
Change the outline: python3 tools/pokeball_preset.py --radius 1500 --band 160 --button 280 --ring 120 (all in blocks), then search seeds again and rebuild the template. For other shapes, edit the preset JSON by hand (field reference: the WorldGen Editor wiki; the previewer shows outlines before generating). Keep temperature at standard and don't use exclude_biomes: both make WorldGen Editor swap cave biomes for surface fallbacks and let unlisted biomes in. If the ball gets bigger, raise pregen_radius in world.json too.
Change which biomes exist, or what replaces what: edit biomes.json, run tools/biome_layout.py, then search seeds again. Where a biome lands depends on the seed's climate noise, not on the lobes.
Hand edits on the finished world (paths, landmarks, a reshaped coast):
- WorldPainter (desktop): import
build/world-template(File → Import → Existing Minecraft map), edit, and export it back to a folder. Keep a copy first. WorldPainter rewrites chunks and may drop Cobblemon data in those chunks, so edit before anyone plays on the world. - In-game, in creative on the Prism save: build normally, or use a world-edit mod for larger changes. Then copy the save back over
build/world-templateand runpython3 tools/world_report.pyto re-check ore and border.
Hand edits are lost when the template is regenerated, so keep them few, or export them as structures.
Ore
There is no natural ore. NeoForge's remove_features biome modifier (datapacks/core/.../biome_modifier/no_natural_ores.json) removes vanilla ore features. Cobblemon's evolution-stone ores are added from code, so they are switched off by overriding their placed features with zero placements (tools/cobblemon_ore_overrides.py; re-run it after a Cobblemon update). The large copper/iron ore veins are turned off in the overridden WorldGen Editor noise settings (ore_veins_enabled: false). Structures and fossils that have ore built in (Cobblemon habitats and ruins, vanilla fossils) keep their shape, but tools/clean_structures.py makes their processors turn ore into stone (re-run it after a mod update). Nether fortresses and Nether ruined portals can't appear in the basalt-delta caves (their biome tags leave basalt deltas out). tools/world_report.py scans every block of every chunk for anything ending in _ore, ancient debris and raw ore blocks.
Mobs
Only Pokémon. The companion mod (mod/.../world/OnlyPokemon.kt) never lets a vanilla mob join a world unless it is loaded from a save (exceptions: entity type tag cobblesurvival:allowed_vanilla_mobs, for now the Ender Dragon). That covers mobs that structures place during generation, so all structures stay. When a chunk has just been generated it also removes spawners and trial spawners (block tag cobblesurvival:removed_on_generation), stops sculk shriekers from summoning the Warden, and turns infested blocks back into normal ones. Underneath, vanilla spawn lists are emptied (no_vanilla_spawns.json), infested stone doesn't generate (no_infested_stone.json) and the template has doMobSpawning false. tools/world_report.py fails if the world stores any vanilla mob or mob source.