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:
commit
398301f0be
232 files changed
+72665
No files matched your search
@@ -0,0 +1,53 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
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 data
|
||||
- `build/island-map.png`: top-down biome map with zone outlines, border and spawn
|
||||
- `build/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](https://github.com/waterflane/WorldGen-Editor/wiki); the [previewer](https://github.com/waterflane/WorldGen-Editor-Preview) 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-template` and run `python3 tools/world_report.py` to 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.
|
||||
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"_comment": "Biome set of the island. tools/biome_layout.py reads vanilla's overworld biome parameters, sends every vanilla biome to its target below, adds the extra entries and writes the world type. Adrian's list (2026-10-28): cherry grove, mangrove swamp, deep dark, jagged peaks, lush caves, dripstone caves, basalt deltas (as a cave biome; no Nether), jungle, desert, badlands, mountain edge, plains, forest. 'Mountain edge' no longer exists (removed in 1.18); windswept hills is its closest successor.",
|
||||
"allowed": [
|
||||
"minecraft:plains",
|
||||
"minecraft:forest",
|
||||
"minecraft:cherry_grove",
|
||||
"minecraft:mangrove_swamp",
|
||||
"minecraft:jungle",
|
||||
"minecraft:desert",
|
||||
"minecraft:badlands",
|
||||
"minecraft:windswept_hills",
|
||||
"minecraft:jagged_peaks",
|
||||
"minecraft:lush_caves",
|
||||
"minecraft:dripstone_caves",
|
||||
"minecraft:deep_dark",
|
||||
"minecraft:basalt_deltas"
|
||||
],
|
||||
"water": [
|
||||
"minecraft:ocean",
|
||||
"minecraft:deep_ocean",
|
||||
"minecraft:lukewarm_ocean",
|
||||
"minecraft:deep_lukewarm_ocean",
|
||||
"minecraft:warm_ocean",
|
||||
"minecraft:river",
|
||||
"minecraft:beach"
|
||||
],
|
||||
"remap": {
|
||||
"minecraft:plains": "minecraft:plains",
|
||||
"minecraft:sunflower_plains": "minecraft:plains",
|
||||
"minecraft:snowy_plains": "minecraft:plains",
|
||||
"minecraft:ice_spikes": "minecraft:plains",
|
||||
"minecraft:mushroom_fields": "minecraft:plains",
|
||||
"minecraft:forest": "minecraft:forest",
|
||||
"minecraft:flower_forest": "minecraft:forest",
|
||||
"minecraft:birch_forest": "minecraft:forest",
|
||||
"minecraft:old_growth_birch_forest": "minecraft:forest",
|
||||
"minecraft:dark_forest": "minecraft:forest",
|
||||
"minecraft:taiga": "minecraft:forest",
|
||||
"minecraft:snowy_taiga": "minecraft:forest",
|
||||
"minecraft:old_growth_pine_taiga": "minecraft:forest",
|
||||
"minecraft:old_growth_spruce_taiga": "minecraft:forest",
|
||||
"minecraft:windswept_forest": "minecraft:forest",
|
||||
"minecraft:grove": "minecraft:forest",
|
||||
"minecraft:meadow": "minecraft:cherry_grove",
|
||||
"minecraft:cherry_grove": "minecraft:cherry_grove",
|
||||
"minecraft:swamp": "minecraft:mangrove_swamp",
|
||||
"minecraft:mangrove_swamp": "minecraft:mangrove_swamp",
|
||||
"minecraft:jungle": "minecraft:jungle",
|
||||
"minecraft:sparse_jungle": "minecraft:jungle",
|
||||
"minecraft:bamboo_jungle": "minecraft:jungle",
|
||||
"minecraft:desert": "minecraft:desert",
|
||||
"minecraft:savanna": "minecraft:desert",
|
||||
"minecraft:savanna_plateau": "minecraft:badlands",
|
||||
"minecraft:windswept_savanna": "minecraft:badlands",
|
||||
"minecraft:badlands": "minecraft:badlands",
|
||||
"minecraft:eroded_badlands": "minecraft:badlands",
|
||||
"minecraft:wooded_badlands": "minecraft:badlands",
|
||||
"minecraft:windswept_hills": "minecraft:windswept_hills",
|
||||
"minecraft:windswept_gravelly_hills": "minecraft:windswept_hills",
|
||||
"minecraft:snowy_slopes": "minecraft:windswept_hills",
|
||||
"minecraft:stony_shore": "minecraft:windswept_hills",
|
||||
"minecraft:jagged_peaks": "minecraft:jagged_peaks",
|
||||
"minecraft:frozen_peaks": "minecraft:jagged_peaks",
|
||||
"minecraft:stony_peaks": "minecraft:jagged_peaks",
|
||||
"minecraft:river": "minecraft:river",
|
||||
"minecraft:frozen_river": "minecraft:river",
|
||||
"minecraft:beach": "minecraft:beach",
|
||||
"minecraft:snowy_beach": "minecraft:beach",
|
||||
"minecraft:ocean": "minecraft:ocean",
|
||||
"minecraft:cold_ocean": "minecraft:ocean",
|
||||
"minecraft:frozen_ocean": "minecraft:ocean",
|
||||
"minecraft:deep_ocean": "minecraft:deep_ocean",
|
||||
"minecraft:deep_cold_ocean": "minecraft:deep_ocean",
|
||||
"minecraft:deep_frozen_ocean": "minecraft:deep_ocean",
|
||||
"minecraft:lukewarm_ocean": "minecraft:lukewarm_ocean",
|
||||
"minecraft:deep_lukewarm_ocean": "minecraft:deep_lukewarm_ocean",
|
||||
"minecraft:warm_ocean": "minecraft:warm_ocean",
|
||||
"minecraft:lush_caves": "minecraft:lush_caves",
|
||||
"minecraft:dripstone_caves": "minecraft:dripstone_caves",
|
||||
"minecraft:deep_dark": "minecraft:deep_dark"
|
||||
},
|
||||
"add": [
|
||||
{
|
||||
"_comment": "Volcanic caves under the hottest, driest land (where desert and badlands are), at cave depth like lush and dripstone caves.",
|
||||
"biome": "minecraft:basalt_deltas",
|
||||
"parameters": {
|
||||
"temperature": [0.55, 1.0],
|
||||
"humidity": [-1.0, -0.1],
|
||||
"continentalness": [-0.11, 1.0],
|
||||
"erosion": [-1.0, 1.0],
|
||||
"weirdness": [-1.0, 1.0],
|
||||
"depth": [0.2, 0.9],
|
||||
"offset": 0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "Cobblemon Survival Island",
|
||||
"seed": "isle-26",
|
||||
"level_type": "cobblesurvival:island",
|
||||
"preset": "pack/config/worldgen_editor/presets/cobblesurvival_island.json",
|
||||
"pregen_radius": 1700,
|
||||
"border_margin": 96,
|
||||
"chunky": {
|
||||
"url": "https://cdn.modrinth.com/data/fALzjamp/versions/LuFhm4eU/Chunky-NeoForge-1.4.23.jar",
|
||||
"sha1": "ab0c74743a653020fe2dfc4986b43e893947f3e9"
|
||||
},
|
||||
"gamerules": {
|
||||
"doMobSpawning": false
|
||||
},
|
||||
"quick_check": {
|
||||
"spawn_radius": 128,
|
||||
"structure_radius": 96,
|
||||
"structures": [
|
||||
"minecraft:stronghold",
|
||||
"minecraft:mineshaft",
|
||||
"minecraft:trial_chambers",
|
||||
"minecraft:ancient_city",
|
||||
"#minecraft:village",
|
||||
"minecraft:monument",
|
||||
"#minecraft:ocean_ruin",
|
||||
"cobblemon:ruins/rooted_gimmi_tower",
|
||||
"cobblemon:ruins/temperate_gimmi_tower",
|
||||
"cobblemon:habitats/natural_lightningrod"
|
||||
],
|
||||
"absent_structures": [
|
||||
"#minecraft:ruined_portal"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"_comment": "Zone plan for Phase 3 (model approved by Adrian 2026-10-29; levels are placeholders, see docs/balance.md). tools/zone_layout.py assigns each surface cell of the island to the first zone whose rule matches, in this order, and renders build/zone-map.png. Rules: 'within' = distance from 0,0 in blocks; 'biomes' = cells of these biomes, clusters smaller than min_cells dropped, plus 'absorb' = cells of other biomes within that many blocks of the cluster; 'region' = what is left, by half-plane (x/z bounds in blocks); 'water' = sea cells of these biomes. Biomes in 'inherit' (rivers) take the zone of the land around them. Cave zones follow the cave biome everywhere under the island and are not drawn. 'lines' = how many evolution lines tools/zone_spawns.py aims to give the zone (scaled to the lines available); 'species' pins a line to a zone by hand.",
|
||||
"min_cells": 6,
|
||||
"inherit": ["minecraft:river"],
|
||||
"species": {"durant": "basalt", "torkoal": "basalt", "heatmor": "basalt"},
|
||||
"zones": [
|
||||
{
|
||||
"id": "button_isle", "lines": 20, "name": "Button Isle", "levels": [2, 10], "hazard": "none", "color": "#a6d96a",
|
||||
"rule": {"within": 300}
|
||||
},
|
||||
{
|
||||
"id": "frostpeak", "lines": 30, "name": "Frostpeak Range", "levels": [40, 55], "hazard": "cold (Cold Sweat): needs wool insulation", "color": "#f2f7ff",
|
||||
"rule": {"biomes": ["minecraft:jagged_peaks"], "absorb": {"minecraft:windswept_hills": 96, "minecraft:cherry_grove": 144}}
|
||||
},
|
||||
{
|
||||
"id": "sunscorch", "lines": 25, "name": "Sunscorch", "levels": [30, 45], "hazard": "heat (Cold Sweat): needs heat insulation", "color": "#f4a443",
|
||||
"rule": {"biomes": ["minecraft:desert", "minecraft:badlands"]}
|
||||
},
|
||||
{
|
||||
"id": "mire", "lines": 25, "name": "Mangrove Mire", "levels": [25, 38], "hazard": "poison area effect (companion mod)", "color": "#3cb5a0",
|
||||
"rule": {"biomes": ["minecraft:mangrove_swamp"]}
|
||||
},
|
||||
{
|
||||
"id": "jungle", "lines": 30, "name": "Verdant Jungle", "levels": [18, 30], "hazard": "none (warm and humid, below Cold Sweat's damage)", "color": "#5a8f1e",
|
||||
"rule": {"biomes": ["minecraft:jungle"]}
|
||||
},
|
||||
{
|
||||
"id": "highlands", "lines": 35, "name": "Highland Meadows", "levels": [25, 35], "hazard": "none", "color": "#e3b7d6",
|
||||
"rule": {"region": {"z_max": 0, "x_min": -250}}
|
||||
},
|
||||
{
|
||||
"id": "westmarch", "lines": 35, "name": "Westmarch", "levels": [15, 25], "hazard": "none", "color": "#2f8f4e",
|
||||
"rule": {"region": {"z_max": 0, "x_max": -250}}
|
||||
},
|
||||
{
|
||||
"id": "southwold", "lines": 35, "name": "Southwold", "levels": [8, 18], "hazard": "none", "color": "#7cc576",
|
||||
"rule": {"region": {"z_min": 0}}
|
||||
},
|
||||
{
|
||||
"id": "shallows", "lines": 30, "name": "Shallows", "levels": [5, 20], "hazard": "none", "color": "#5aa9e6",
|
||||
"rule": {"water": ["minecraft:river", "minecraft:beach", "minecraft:ocean", "minecraft:lukewarm_ocean", "minecraft:warm_ocean"]}
|
||||
},
|
||||
{
|
||||
"id": "deep_sea", "lines": 20, "name": "Deep Sea", "levels": [30, 50], "hazard": "none", "color": "#1f4e8c",
|
||||
"rule": {"water": ["minecraft:deep_ocean", "minecraft:deep_lukewarm_ocean"]}
|
||||
}
|
||||
],
|
||||
"caves": [
|
||||
{"id": "lush_caves", "lines": 20, "name": "Lush Caves", "biome": "minecraft:lush_caves", "levels": [12, 28], "hazard": "none"},
|
||||
{"id": "dripstone", "lines": 20, "name": "Dripstone Depths", "biome": "minecraft:dripstone_caves", "levels": [22, 38], "hazard": "none"},
|
||||
{"id": "deep_dark", "lines": 20, "name": "Deep Dark", "biome": "minecraft:deep_dark", "levels": [45, 60], "hazard": "darkness (vanilla sculk; no Warden)"},
|
||||
{"id": "basalt", "lines": 15, "name": "Basalt Furnace", "biome": "minecraft:basalt_deltas", "levels": [55, 70], "hazard": "heat (Cold Sweat)"}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user