Phase 3: strong flyers only spawn in high-level zones

- tools/zone_spawns.py: a species ridable through the air with top
  speed >= 60 or top stamina >= 85 never spawns in a zone whose band
  starts below Lv 30; lines that start as one are only placed in such
  zones, and the tool refuses to write pools that break the rule.
  Drampa moves to Sunscorch; Aerodactyl is fossil-only; Salamence never
  spawns wild (Bagon and Shelgon stay in the Dripstone caves).
- Ride stats stay Cobblemon's until play-tested (species_additions can
  override riding later).
- Phase 3 checklist: all steps in, approval checkpoint for Adrian.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-30 02:01:44 +01:00
1 parent 173203eeb5
commit 55c336f89e
12 files changed
+2115 -576

No files matched your search

@@ -1,7 +1,7 @@
{
"_comment": "Generated by tools/zone_spawns.py from world/zones.json; do not edit by hand.",
"zone": "westmarch",
"pokemon": "pinsir level=30 uncatchable=yes",
"pokemon": "scyther level=30 uncatchable=yes",
"scale": 1.5,
"drops": [
{
File diff suppressed because it is too large. Load diff
@@ -13,24 +13,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-aerodactyl-1-0",
"level": "27-28",
"pokemon": "aerodactyl",
"presets": [],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 100.0
},
{
"bucket": "ultra-rare",
"condition": {
"biomes": [
"#cobblemon:is_lush"
],
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-amaura-1-1",
"id": "lush_caves-amaura-1-0",
"level": "12-28",
"pokemon": "amaura",
"presets": [],
@@ -47,7 +30,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-anorith-1-2",
"id": "lush_caves-anorith-1-1",
"level": "12-28",
"pokemon": "anorith",
"presets": [],
@@ -64,7 +47,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-anorith-2-3",
"id": "lush_caves-anorith-2-2",
"level": "12-28",
"pokemon": "anorith",
"presets": [
@@ -83,7 +66,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-archen-1-4",
"id": "lush_caves-archen-1-3",
"level": "15-28",
"pokemon": "archen",
"presets": [],
@@ -107,7 +90,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-carnivine-2-22",
"id": "lush_caves-carnivine-2-21",
"level": "20-28",
"pokemon": "carnivine",
"presets": [],
@@ -124,7 +107,7 @@
"maxSkyLight": 15,
"zone": "lush_caves"
},
"id": "lush_caves-cranidos-1-5",
"id": "lush_caves-cranidos-1-4",
"level": "12-28",
"pokemon": "cranidos",
"presets": [],
@@ -148,7 +131,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-ferroseed-1-6",
"id": "lush_caves-ferroseed-1-5",
"level": "12-28",
"pokemon": "ferroseed",
"presets": [],
@@ -171,7 +154,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-kabuto-1-7",
"id": "lush_caves-kabuto-1-6",
"level": "12-28",
"pokemon": "kabuto",
"presets": [],
@@ -188,7 +171,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-kabuto-2-8",
"id": "lush_caves-kabuto-2-7",
"level": "12-28",
"pokemon": "kabuto",
"presets": [
@@ -207,7 +190,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-lileep-1-9",
"id": "lush_caves-lileep-1-8",
"level": "12-28",
"pokemon": "lileep",
"presets": [
@@ -226,7 +209,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-lileep-2-10",
"id": "lush_caves-lileep-2-9",
"level": "12-28",
"pokemon": "lileep",
"presets": [
@@ -252,7 +235,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-morelull-2-23",
"id": "lush_caves-morelull-2-22",
"level": "12-28",
"pokemon": "morelull",
"presets": [],
@@ -275,7 +258,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-omanyte-1-11",
"id": "lush_caves-omanyte-1-10",
"level": "12-28",
"pokemon": "omanyte",
"presets": [],
@@ -292,7 +275,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-omanyte-2-12",
"id": "lush_caves-omanyte-2-11",
"level": "12-28",
"pokemon": "omanyte",
"presets": [
@@ -318,7 +301,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-paras-1-13",
"id": "lush_caves-paras-1-12",
"level": "12-28",
"pokemon": "paras",
"presets": [],
@@ -348,7 +331,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-parasect-1-14",
"id": "lush_caves-parasect-1-13",
"level": "24-28",
"pokemon": "parasect",
"presets": [],
@@ -371,7 +354,7 @@
"maxSkyLight": 15,
"zone": "lush_caves"
},
"id": "lush_caves-shieldon-1-15",
"id": "lush_caves-shieldon-1-14",
"level": "12-28",
"pokemon": "shieldon",
"presets": [],
@@ -395,7 +378,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-shiinotic-2-24",
"id": "lush_caves-shiinotic-2-23",
"level": "24-28",
"pokemon": "shiinotic",
"presets": [],
@@ -425,7 +408,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-shuckle-1-16",
"id": "lush_caves-shuckle-1-15",
"level": "16-28",
"pokemon": "shuckle",
"presets": [],
@@ -450,7 +433,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-shuckle-2-17",
"id": "lush_caves-shuckle-2-16",
"level": "16-28",
"pokemon": "shuckle",
"spawnablePositionType": "fishing",
@@ -474,7 +457,7 @@
"minLureLevel": 1,
"zone": "lush_caves"
},
"id": "lush_caves-shuckle-3-18",
"id": "lush_caves-shuckle-3-17",
"level": "16-28",
"pokemon": "shuckle",
"spawnablePositionType": "fishing",
@@ -496,7 +479,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-tirtouga-1-19",
"id": "lush_caves-tirtouga-1-18",
"level": "15-28",
"pokemon": "tirtouga",
"presets": [],
@@ -513,7 +496,7 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-tirtouga-2-20",
"id": "lush_caves-tirtouga-2-19",
"level": "15-28",
"pokemon": "tirtouga",
"presets": [
@@ -532,13 +515,73 @@
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-tyrunt-1-21",
"id": "lush_caves-tyrunt-1-20",
"level": "12-28",
"pokemon": "tyrunt",
"presets": [],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 60.0
},
{
"anticondition": {
"maxY": 9,
"minY": -41,
"structures": [
"cobblemon:shipwreck_coves/lush_shipwreck_cove"
]
},
"bucket": "common",
"condition": {
"biomes": [
"#cobblemon:is_lush"
],
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-venipede-3-24",
"level": "12-26",
"pokemon": "venipede",
"presets": [],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 9.0,
"weightMultiplier": {
"condition": {
"isPokeSnack": true
},
"multiplier": 2.0
}
},
{
"anticondition": {
"maxY": 9,
"minY": -41,
"structures": [
"cobblemon:shipwreck_coves/lush_shipwreck_cove"
]
},
"bucket": "common",
"condition": {
"biomes": [
"#cobblemon:is_lush"
],
"maxSkyLight": 7,
"zone": "lush_caves"
},
"id": "lush_caves-whirlipede-3-25",
"level": "22-28",
"pokemon": "whirlipede",
"presets": [],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 1.8,
"weightMultiplier": {
"condition": {
"isPokeSnack": true
},
"multiplier": 2.0
}
}
]
}
@@ -49,7 +49,7 @@
],
"zone": "mire"
},
"id": "mire-appletun-1-94",
"id": "mire-appletun-1-86",
"level": "25-38",
"pokemon": "appletun",
"presets": [
@@ -77,7 +77,7 @@
],
"zone": "mire"
},
"id": "mire-appletun-2-95",
"id": "mire-appletun-2-87",
"level": "25-38",
"pokemon": "appletun",
"presets": [
@@ -106,7 +106,7 @@
],
"zone": "mire"
},
"id": "mire-applin-1-90",
"id": "mire-applin-1-82",
"level": "25-26",
"pokemon": "applin",
"presets": [
@@ -134,7 +134,7 @@
],
"zone": "mire"
},
"id": "mire-applin-2-91",
"id": "mire-applin-2-83",
"level": "25-26",
"pokemon": "applin",
"presets": [
@@ -159,7 +159,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-arcanine-1-121",
"id": "mire-arcanine-1-113",
"level": "30-38",
"pokemon": "arcanine",
"presets": [
@@ -471,33 +471,6 @@
}
]
},
{
"bucket": "rare",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-chansey-1-82",
"level": "25-38",
"pokemon": "chansey",
"presets": [
"natural",
"urban"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 62.6,
"weightMultiplier": {
"condition": {
"timeRange": "night"
},
"multiplier": 0.25
}
},
{
"bucket": "common",
"condition": {
@@ -542,7 +515,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-deino-2-138",
"id": "mire-deino-2-130",
"level": "25-30",
"pokemon": "deino",
"presets": [
@@ -577,7 +550,7 @@
],
"zone": "mire"
},
"id": "mire-dipplin-1-96",
"id": "mire-dipplin-1-88",
"level": "25-38",
"pokemon": "dipplin",
"presets": [
@@ -605,7 +578,7 @@
],
"zone": "mire"
},
"id": "mire-dipplin-2-97",
"id": "mire-dipplin-2-89",
"level": "25-38",
"pokemon": "dipplin",
"presets": [
@@ -775,7 +748,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dragonair-1-128",
"id": "mire-dragonair-1-120",
"level": "30-38",
"pokemon": "dragonair",
"presets": [
@@ -809,7 +782,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dragonair-2-129",
"id": "mire-dragonair-2-121",
"level": "30-38",
"pokemon": "dragonair",
"presets": [
@@ -844,7 +817,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dragonair-3-130",
"id": "mire-dragonair-3-122",
"level": "30-38",
"pokemon": "dragonair",
"spawnablePositionType": "fishing",
@@ -868,7 +841,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dragonair-4-131",
"id": "mire-dragonair-4-123",
"level": "30-38",
"pokemon": "dragonair",
"presets": [
@@ -901,7 +874,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dragonair-5-132",
"id": "mire-dragonair-5-124",
"level": "30-38",
"pokemon": "dragonair",
"presets": [
@@ -935,7 +908,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dragonair-6-133",
"id": "mire-dragonair-6-125",
"level": "30-38",
"pokemon": "dragonair",
"spawnablePositionType": "fishing",
@@ -960,7 +933,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dratini-1-122",
"id": "mire-dratini-1-114",
"level": "25-30",
"pokemon": "dratini",
"presets": [
@@ -994,7 +967,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dratini-2-123",
"id": "mire-dratini-2-115",
"level": "25-30",
"pokemon": "dratini",
"presets": [
@@ -1029,7 +1002,7 @@
"minY": -31,
"zone": "mire"
},
"id": "mire-dratini-3-124",
"id": "mire-dratini-3-116",
"level": "25-30",
"pokemon": "dratini",
"spawnablePositionType": "fishing",
@@ -1053,7 +1026,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dratini-4-125",
"id": "mire-dratini-4-117",
"level": "25-30",
"pokemon": "dratini",
"presets": [
@@ -1086,7 +1059,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dratini-5-126",
"id": "mire-dratini-5-118",
"level": "25-30",
"pokemon": "dratini",
"presets": [
@@ -1120,7 +1093,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-dratini-6-127",
"id": "mire-dratini-6-119",
"level": "25-30",
"pokemon": "dratini",
"spawnablePositionType": "fishing",
@@ -1290,7 +1263,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-blue-4-105",
"id": "mire-flabebe-blue-4-97",
"level": "25-30",
"pokemon": "flabebe flower=blue",
"presets": [
@@ -1320,7 +1293,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-orange-3-104",
"id": "mire-flabebe-orange-3-96",
"level": "25-30",
"pokemon": "flabebe flower=orange",
"presets": [
@@ -1350,7 +1323,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-pink-6-107",
"id": "mire-flabebe-pink-6-99",
"level": "25-30",
"pokemon": "flabebe flower=pink",
"presets": [
@@ -1380,7 +1353,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-red-1-102",
"id": "mire-flabebe-red-1-94",
"level": "25-30",
"pokemon": "flabebe flower=red",
"presets": [
@@ -1410,7 +1383,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-white-5-106",
"id": "mire-flabebe-white-5-98",
"level": "25-30",
"pokemon": "flabebe flower=white",
"presets": [
@@ -1440,7 +1413,7 @@
],
"zone": "mire"
},
"id": "mire-flabebe-yellow-2-103",
"id": "mire-flabebe-yellow-2-95",
"level": "25-30",
"pokemon": "flabebe flower=yellow",
"presets": [
@@ -1533,7 +1506,7 @@
],
"zone": "mire"
},
"id": "mire-flapple-1-92",
"id": "mire-flapple-1-84",
"level": "25-38",
"pokemon": "flapple",
"presets": [
@@ -1561,7 +1534,7 @@
],
"zone": "mire"
},
"id": "mire-flapple-2-93",
"id": "mire-flapple-2-85",
"level": "25-38",
"pokemon": "flapple",
"presets": [
@@ -1585,7 +1558,7 @@
],
"zone": "mire"
},
"id": "mire-floette-blue-4-111",
"id": "mire-floette-blue-4-103",
"level": "25-37",
"pokemon": "floette flower=blue",
"presets": [
@@ -1615,7 +1588,7 @@
],
"zone": "mire"
},
"id": "mire-floette-orange-3-110",
"id": "mire-floette-orange-3-102",
"level": "25-37",
"pokemon": "floette flower=orange",
"presets": [
@@ -1645,7 +1618,7 @@
],
"zone": "mire"
},
"id": "mire-floette-pink-6-113",
"id": "mire-floette-pink-6-105",
"level": "25-37",
"pokemon": "floette flower=pink",
"presets": [
@@ -1675,7 +1648,7 @@
],
"zone": "mire"
},
"id": "mire-floette-red-1-108",
"id": "mire-floette-red-1-100",
"level": "25-37",
"pokemon": "floette flower=red",
"presets": [
@@ -1705,7 +1678,7 @@
],
"zone": "mire"
},
"id": "mire-floette-white-5-112",
"id": "mire-floette-white-5-104",
"level": "25-37",
"pokemon": "floette flower=white",
"presets": [
@@ -1735,7 +1708,7 @@
],
"zone": "mire"
},
"id": "mire-floette-yellow-2-109",
"id": "mire-floette-yellow-2-101",
"level": "25-37",
"pokemon": "floette flower=yellow",
"presets": [
@@ -1765,7 +1738,7 @@
],
"zone": "mire"
},
"id": "mire-florges-blue-4-117",
"id": "mire-florges-blue-4-109",
"level": "32-38",
"pokemon": "florges flower=blue",
"presets": [
@@ -1795,7 +1768,7 @@
],
"zone": "mire"
},
"id": "mire-florges-orange-3-116",
"id": "mire-florges-orange-3-108",
"level": "32-38",
"pokemon": "florges flower=orange",
"presets": [
@@ -1825,7 +1798,7 @@
],
"zone": "mire"
},
"id": "mire-florges-pink-6-119",
"id": "mire-florges-pink-6-111",
"level": "32-38",
"pokemon": "florges flower=pink",
"presets": [
@@ -1855,7 +1828,7 @@
],
"zone": "mire"
},
"id": "mire-florges-red-1-114",
"id": "mire-florges-red-1-106",
"level": "32-38",
"pokemon": "florges flower=red",
"presets": [
@@ -1885,7 +1858,7 @@
],
"zone": "mire"
},
"id": "mire-florges-white-5-118",
"id": "mire-florges-white-5-110",
"level": "32-38",
"pokemon": "florges flower=white",
"presets": [
@@ -1915,7 +1888,7 @@
],
"zone": "mire"
},
"id": "mire-florges-yellow-2-115",
"id": "mire-florges-yellow-2-107",
"level": "32-38",
"pokemon": "florges flower=yellow",
"presets": [
@@ -2125,7 +2098,7 @@
"minY": 0,
"zone": "mire"
},
"id": "mire-gabite-3-136",
"id": "mire-gabite-3-128",
"level": "25-38",
"pokemon": "gabite",
"presets": [
@@ -2157,7 +2130,7 @@
],
"zone": "mire"
},
"id": "mire-gabite-4-137",
"id": "mire-gabite-4-129",
"level": "25-38",
"pokemon": "gabite",
"presets": [
@@ -2189,7 +2162,7 @@
"minY": 0,
"zone": "mire"
},
"id": "mire-gible-3-134",
"id": "mire-gible-3-126",
"level": "25-30",
"pokemon": "gible",
"presets": [
@@ -2221,7 +2194,7 @@
],
"zone": "mire"
},
"id": "mire-gible-4-135",
"id": "mire-gible-4-127",
"level": "25-30",
"pokemon": "gible",
"presets": [
@@ -2242,7 +2215,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-1-139",
"id": "mire-goomy-1-131",
"level": "25-30",
"pokemon": "goomy",
"presets": [
@@ -2265,7 +2238,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-2-140",
"id": "mire-goomy-2-132",
"level": "25-30",
"pokemon": "goomy",
"presets": [
@@ -2288,7 +2261,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-3-141",
"id": "mire-goomy-3-133",
"level": "25-30",
"pokemon": "goomy",
"presets": [
@@ -2310,7 +2283,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-4-142",
"id": "mire-goomy-4-134",
"level": "25-30",
"pokemon": "goomy",
"spawnablePositionType": "fishing",
@@ -2328,7 +2301,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-5-143",
"id": "mire-goomy-5-135",
"level": "25-30",
"pokemon": "goomy",
"spawnablePositionType": "fishing",
@@ -2355,7 +2328,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-goomy-6-144",
"id": "mire-goomy-6-136",
"level": "25-30",
"pokemon": "goomy",
"spawnablePositionType": "fishing",
@@ -2381,7 +2354,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-12-147",
"id": "mire-goomy-hisui-12-139",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"spawnablePositionType": "fishing",
@@ -2408,7 +2381,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-13-148",
"id": "mire-goomy-hisui-13-140",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"spawnablePositionType": "fishing",
@@ -2434,7 +2407,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-14-149",
"id": "mire-goomy-hisui-14-141",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"spawnablePositionType": "fishing",
@@ -2460,7 +2433,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-15-150",
"id": "mire-goomy-hisui-15-142",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"spawnablePositionType": "fishing",
@@ -2486,7 +2459,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-16-151",
"id": "mire-goomy-hisui-16-143",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"spawnablePositionType": "fishing",
@@ -2520,7 +2493,7 @@
],
"zone": "mire"
},
"id": "mire-goomy-hisui-8-145",
"id": "mire-goomy-hisui-8-137",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"presets": [
@@ -2548,7 +2521,7 @@
"minSkyLight": 0,
"zone": "mire"
},
"id": "mire-goomy-hisui-9-146",
"id": "mire-goomy-hisui-9-138",
"level": "25-30",
"pokemon": "goomy region_bias=hisui",
"presets": [
@@ -2659,7 +2632,7 @@
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-growlithe-1-120",
"id": "mire-growlithe-1-112",
"level": "25-35",
"pokemon": "growlithe",
"presets": [
@@ -2670,108 +2643,6 @@
"type": "pokemon",
"weight": 92.0
},
{
"bucket": "common",
"condition": {
"biomes": [
"#cobblemon:is_freshwater",
"#cobblemon:is_ocean"
],
"canSeeSky": true,
"isPokeSnack": true,
"zone": "mire"
},
"id": "mire-gyarados-1-83",
"level": "25-38",
"pokemon": "gyarados",
"presets": [
"water"
],
"spawnablePositionType": "submerged",
"type": "pokemon",
"weight": 0.6
},
{
"bucket": "common",
"condition": {
"biomes": [
"#cobblemon:is_freshwater",
"#cobblemon:is_ocean"
],
"canSeeSky": false,
"isPokeSnack": true,
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-gyarados-2-84",
"level": "25-38",
"pokemon": "gyarados",
"presets": [
"water"
],
"spawnablePositionType": "submerged",
"type": "pokemon",
"weight": 0.6
},
{
"bucket": "uncommon",
"condition": {
"biomes": [
"#cobblemon:is_freshwater",
"#cobblemon:is_ocean"
],
"isPokeSnack": true,
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-gyarados-3-85",
"level": "25-38",
"pokemon": "gyarados",
"presets": [
"water"
],
"spawnablePositionType": "surface",
"type": "pokemon",
"weight": 1.6
},
{
"bucket": "common",
"condition": {
"biomes": [
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"canSeeSky": true,
"zone": "mire"
},
"id": "mire-gyarados-4-86",
"level": "25-38",
"pokemon": "gyarados",
"spawnablePositionType": "fishing",
"type": "pokemon",
"weight": 10.0
},
{
"bucket": "common",
"condition": {
"biomes": [
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"canSeeSky": false,
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "mire"
},
"id": "mire-gyarados-5-87",
"level": "25-38",
"pokemon": "gyarados",
"spawnablePositionType": "fishing",
"type": "pokemon",
"weight": 10.0
},
{
"anticondition": {
"biomes": [
@@ -2791,7 +2662,7 @@
],
"zone": "mire"
},
"id": "mire-hydrapple-1-98",
"id": "mire-hydrapple-1-90",
"level": "29-38",
"pokemon": "hydrapple",
"presets": [
@@ -2819,7 +2690,7 @@
],
"zone": "mire"
},
"id": "mire-hydrapple-2-99",
"id": "mire-hydrapple-2-91",
"level": "29-38",
"pokemon": "hydrapple",
"presets": [
@@ -3363,30 +3234,6 @@
"type": "pokemon",
"weight": 60.0
},
{
"bucket": "uncommon",
"condition": {
"biomes": [
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"neededNearbyBlocks": [
"#cobblemon:saccharine_trees"
],
"zone": "mire"
},
"id": "mire-munchlax-2-89",
"level": "25-38",
"pokemon": "munchlax",
"presets": [
"natural"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 16.8
},
{
"bucket": "common",
"condition": {
@@ -3520,30 +3367,6 @@
}
]
},
{
"bucket": "uncommon",
"condition": {
"biomes": [
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"neededNearbyBlocks": [
"#cobblemon:saccharine_trees"
],
"zone": "mire"
},
"id": "mire-snorlax-2-88",
"level": "34-38",
"pokemon": "snorlax",
"presets": [
"natural"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 3.2
},
{
"bucket": "ultra-rare",
"condition": {
@@ -4046,7 +3869,7 @@
],
"zone": "mire"
},
"id": "mire-teddiursa-2-100",
"id": "mire-teddiursa-2-92",
"level": "25-33",
"pokemon": "teddiursa",
"presets": [
@@ -4105,7 +3928,7 @@
],
"zone": "mire"
},
"id": "mire-ursaring-2-101",
"id": "mire-ursaring-2-93",
"level": "30-38",
"pokemon": "ursaring",
"presets": [
@@ -574,28 +574,6 @@
"type": "pokemon",
"weight": 18.0
},
{
"bucket": "uncommon",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"minY": 192,
"zone": "southwold"
},
"id": "southwold-drampa-2-97",
"level": "8-18",
"pokemon": "drampa",
"presets": [
"natural",
"wild"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 60.0
},
{
"anticondition": {
"biomes": [
@@ -1145,7 +1123,7 @@
"minSkyLight": 8,
"zone": "southwold"
},
"id": "southwold-koffing-1-107",
"id": "southwold-koffing-1-106",
"level": "9-18",
"pokemon": "koffing",
"presets": [
@@ -1189,7 +1167,7 @@
],
"zone": "southwold"
},
"id": "southwold-koffing-2-108",
"id": "southwold-koffing-2-107",
"level": "9-18",
"pokemon": "koffing",
"presets": [
@@ -1835,7 +1813,7 @@
"timeRange": "night",
"zone": "southwold"
},
"id": "southwold-munna-1-98",
"id": "southwold-munna-1-97",
"level": "8-18",
"pokemon": "munna",
"presets": [
@@ -1860,7 +1838,7 @@
"timeRange": "night",
"zone": "southwold"
},
"id": "southwold-munna-2-99",
"id": "southwold-munna-2-98",
"level": "8-18",
"pokemon": "munna",
"presets": [
@@ -1939,7 +1917,7 @@
"timeRange": "day",
"zone": "southwold"
},
"id": "southwold-pidove-1-100",
"id": "southwold-pidove-1-99",
"level": "8-18",
"pokemon": "pidove",
"presets": [
@@ -1968,7 +1946,7 @@
"timeRange": "day",
"zone": "southwold"
},
"id": "southwold-pidove-2-101",
"id": "southwold-pidove-2-100",
"level": "8-18",
"pokemon": "pidove",
"presets": [
@@ -2000,7 +1978,7 @@
"timeRange": "day",
"zone": "southwold"
},
"id": "southwold-pidove-3-102",
"id": "southwold-pidove-3-101",
"level": "8-18",
"pokemon": "pidove",
"presets": [
@@ -2296,7 +2274,7 @@
"minSkyLight": 8,
"zone": "southwold"
},
"id": "southwold-sigilyph-2-112",
"id": "southwold-sigilyph-2-111",
"level": "8-18",
"pokemon": "sigilyph",
"presets": [
@@ -2390,6 +2368,32 @@
"type": "pokemon",
"weight": 54.0
},
{
"bucket": "rare",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "southwold"
},
"id": "southwold-solosis-1-112",
"level": "8-18",
"pokemon": "solosis",
"presets": [
"natural"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 12.0,
"weightMultiplier": {
"condition": {
"isPokeSnack": true
},
"multiplier": 1.25
}
},
{
"anticondition": {
"biomes": [
@@ -2666,7 +2670,7 @@
"minY": 96,
"zone": "southwold"
},
"id": "southwold-swablu-1-110",
"id": "southwold-swablu-1-109",
"level": "8-18",
"pokemon": "swablu",
"presets": [
@@ -2703,7 +2707,7 @@
"minY": 192,
"zone": "southwold"
},
"id": "southwold-swablu-2-111",
"id": "southwold-swablu-2-110",
"level": "8-18",
"pokemon": "swablu",
"presets": [
@@ -3024,7 +3028,7 @@
"minSkyLight": 8,
"zone": "southwold"
},
"id": "southwold-voltorb-1-103",
"id": "southwold-voltorb-1-102",
"level": "8-18",
"pokemon": "voltorb",
"presets": [
@@ -3062,7 +3066,7 @@
],
"zone": "southwold"
},
"id": "southwold-voltorb-2-104",
"id": "southwold-voltorb-2-103",
"level": "8-18",
"pokemon": "voltorb",
"presets": [
@@ -3099,7 +3103,7 @@
],
"zone": "southwold"
},
"id": "southwold-voltorb-3-105",
"id": "southwold-voltorb-3-104",
"level": "8-18",
"pokemon": "voltorb",
"spawnablePositionType": "grounded",
@@ -3133,7 +3137,7 @@
],
"zone": "southwold"
},
"id": "southwold-voltorb-hisuian-4-106",
"id": "southwold-voltorb-hisuian-4-105",
"level": "8-18",
"pokemon": "voltorb hisuian",
"presets": [
@@ -3174,7 +3178,7 @@
"minSkyLight": 0,
"zone": "southwold"
},
"id": "southwold-whismur-2-109",
"id": "southwold-whismur-2-108",
"level": "8-18",
"pokemon": "whismur",
"presets": [
@@ -451,6 +451,28 @@
"multiplier": 0.25
}
},
{
"bucket": "uncommon",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"minY": 192,
"zone": "sunscorch"
},
"id": "sunscorch-drampa-2-76",
"level": "30-45",
"pokemon": "drampa",
"presets": [
"natural",
"wild"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 60.0
},
{
"bucket": "common",
"condition": {
@@ -21,7 +21,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-alcremie-1-58",
"id": "westmarch-alcremie-1-57",
"level": "22-25",
"pokemon": "alcremie",
"spawnablePositionType": "grounded",
@@ -53,7 +53,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-alcremie-2-59",
"id": "westmarch-alcremie-2-58",
"level": "22-25",
"pokemon": "alcremie",
"presets": [
@@ -88,7 +88,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-alcremie-3-60",
"id": "westmarch-alcremie-3-59",
"level": "22-25",
"pokemon": "alcremie",
"presets": [
@@ -292,7 +292,7 @@
"canSeeSky": false,
"zone": "westmarch"
},
"id": "westmarch-baltoy-2-77",
"id": "westmarch-baltoy-2-76",
"level": "15-25",
"pokemon": "baltoy",
"presets": [
@@ -319,7 +319,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-boldore-1-112",
"id": "westmarch-boldore-1-111",
"level": "25-25",
"pokemon": "boldore",
"presets": [
@@ -344,7 +344,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-boltund-1-48",
"id": "westmarch-boltund-1-47",
"level": "25-25",
"pokemon": "boltund",
"presets": [
@@ -387,7 +387,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-boltund-2-49",
"id": "westmarch-boltund-2-48",
"level": "25-25",
"pokemon": "boltund",
"presets": [
@@ -457,7 +457,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-bronzor-2-78",
"id": "westmarch-bronzor-2-77",
"level": "15-25",
"pokemon": "bronzor",
"presets": [
@@ -481,7 +481,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-bronzor-4-79",
"id": "westmarch-bronzor-4-78",
"level": "15-25",
"pokemon": "bronzor",
"spawnablePositionType": "grounded",
@@ -531,7 +531,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-carbink-1-87",
"id": "westmarch-carbink-1-86",
"level": "25-25",
"pokemon": "carbink",
"presets": [
@@ -561,7 +561,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-carkol-1-108",
"id": "westmarch-carkol-1-107",
"level": "18-25",
"pokemon": "carkol",
"presets": [
@@ -584,7 +584,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-charjabug-2-89",
"id": "westmarch-charjabug-2-88",
"level": "20-25",
"pokemon": "charjabug",
"presets": [
@@ -750,7 +750,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-corsola-2-104",
"id": "westmarch-corsola-2-103",
"level": "16-25",
"pokemon": "corsola",
"presets": [
@@ -771,7 +771,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-corsola-galarian-6-105",
"id": "westmarch-corsola-galarian-6-104",
"level": "16-25",
"pokemon": "corsola galarian",
"presets": [
@@ -798,7 +798,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-corsola-galarian-7-106",
"id": "westmarch-corsola-galarian-7-105",
"level": "16-25",
"pokemon": "corsola galarian",
"presets": [
@@ -1033,7 +1033,7 @@
"timeRange": "night",
"zone": "westmarch"
},
"id": "westmarch-drifloon-1-61",
"id": "westmarch-drifloon-1-60",
"level": "15-25",
"pokemon": "drifloon",
"presets": [
@@ -1059,7 +1059,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-drilbur-1-102",
"id": "westmarch-drilbur-1-101",
"level": "15-25",
"pokemon": "drilbur",
"presets": [
@@ -1085,7 +1085,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-dunsparce-1-121",
"id": "westmarch-dunsparce-1-120",
"level": "17-25",
"pokemon": "dunsparce",
"presets": [
@@ -1119,7 +1119,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-eevee-1-123",
"id": "westmarch-eevee-1-122",
"level": "15-25",
"pokemon": "eevee",
"presets": [
@@ -1146,7 +1146,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-eevee-2-124",
"id": "westmarch-eevee-2-123",
"level": "15-25",
"pokemon": "eevee",
"presets": [
@@ -1172,7 +1172,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-eevee-3-125",
"id": "westmarch-eevee-3-124",
"level": "15-25",
"pokemon": "eevee",
"presets": [
@@ -1202,7 +1202,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-eevee-4-126",
"id": "westmarch-eevee-4-125",
"level": "15-25",
"pokemon": "eevee",
"presets": [
@@ -1232,7 +1232,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-farfetchd-1-100",
"id": "westmarch-farfetchd-1-99",
"level": "15-25",
"pokemon": "farfetchd",
"presets": [
@@ -1265,7 +1265,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-farfetchd-galarian-2-101",
"id": "westmarch-farfetchd-galarian-2-100",
"level": "15-25",
"pokemon": "farfetchd galarian",
"presets": [
@@ -1356,7 +1356,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-gastly-1-70",
"id": "westmarch-gastly-1-69",
"level": "15-25",
"pokemon": "gastly",
"presets": [
@@ -1386,7 +1386,7 @@
"canSeeSky": false,
"zone": "westmarch"
},
"id": "westmarch-gastly-2-71",
"id": "westmarch-gastly-2-70",
"level": "15-25",
"pokemon": "gastly",
"presets": [
@@ -1412,7 +1412,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-geodude-1-51",
"id": "westmarch-geodude-1-50",
"level": "15-25",
"pokemon": "geodude",
"presets": [
@@ -1438,7 +1438,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-geodude-2-52",
"id": "westmarch-geodude-2-51",
"level": "15-25",
"pokemon": "geodude",
"presets": [
@@ -1458,7 +1458,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-graveler-1-53",
"id": "westmarch-graveler-1-52",
"level": "25-25",
"pokemon": "graveler",
"presets": [
@@ -1484,7 +1484,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-graveler-2-54",
"id": "westmarch-graveler-2-53",
"level": "25-25",
"pokemon": "graveler",
"presets": [
@@ -1531,7 +1531,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-grimer-2-62",
"id": "westmarch-grimer-2-61",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1574,7 +1574,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-grimer-3-63",
"id": "westmarch-grimer-3-62",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1612,7 +1612,7 @@
"canSeeSky": true,
"zone": "westmarch"
},
"id": "westmarch-grimer-5-64",
"id": "westmarch-grimer-5-63",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1655,7 +1655,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-grimer-6-65",
"id": "westmarch-grimer-6-64",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1696,7 +1696,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-grimer-8-66",
"id": "westmarch-grimer-8-65",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1741,7 +1741,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-grimer-9-67",
"id": "westmarch-grimer-9-66",
"level": "15-25",
"pokemon": "grimer",
"presets": [
@@ -1776,7 +1776,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-grimer-alolan-10-68",
"id": "westmarch-grimer-alolan-10-67",
"level": "15-25",
"pokemon": "grimer alolan",
"presets": [
@@ -1814,7 +1814,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-grimer-alolan-11-69",
"id": "westmarch-grimer-alolan-11-68",
"level": "15-25",
"pokemon": "grimer alolan",
"presets": [
@@ -1851,7 +1851,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-grubbin-2-88",
"id": "westmarch-grubbin-2-87",
"level": "15-25",
"pokemon": "grubbin",
"presets": [
@@ -1883,7 +1883,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-gurdurr-1-95",
"id": "westmarch-gurdurr-1-94",
"level": "25-25",
"pokemon": "gurdurr",
"presets": [
@@ -1927,7 +1927,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-gurdurr-2-96",
"id": "westmarch-gurdurr-2-95",
"level": "25-25",
"pokemon": "gurdurr",
"presets": [
@@ -1968,7 +1968,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-haunter-1-72",
"id": "westmarch-haunter-1-71",
"level": "25-25",
"pokemon": "haunter",
"presets": [
@@ -1998,7 +1998,7 @@
"canSeeSky": false,
"zone": "westmarch"
},
"id": "westmarch-haunter-2-73",
"id": "westmarch-haunter-2-72",
"level": "25-25",
"pokemon": "haunter",
"presets": [
@@ -2029,7 +2029,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-hawlucha-2-86",
"id": "westmarch-hawlucha-2-85",
"level": "25-25",
"pokemon": "hawlucha",
"presets": [
@@ -2065,7 +2065,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-heracross-1-75",
"id": "westmarch-heracross-1-74",
"level": "25-25",
"pokemon": "heracross",
"presets": [
@@ -2102,7 +2102,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-heracross-3-76",
"id": "westmarch-heracross-3-75",
"level": "25-25",
"pokemon": "heracross",
"presets": [
@@ -2134,7 +2134,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-herdier-1-82",
"id": "westmarch-herdier-1-81",
"level": "16-25",
"pokemon": "herdier",
"presets": [
@@ -2169,7 +2169,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-herdier-2-83",
"id": "westmarch-herdier-2-82",
"level": "16-25",
"pokemon": "herdier",
"presets": [
@@ -2198,7 +2198,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-honedge-2-84",
"id": "westmarch-honedge-2-83",
"level": "15-25",
"pokemon": "honedge",
"spawnablePositionType": "grounded",
@@ -2220,7 +2220,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-honedge-3-85",
"id": "westmarch-honedge-3-84",
"level": "15-25",
"pokemon": "honedge",
"presets": [
@@ -2241,7 +2241,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-kirlia-2-117",
"id": "westmarch-kirlia-2-116",
"level": "20-25",
"pokemon": "kirlia",
"presets": [
@@ -2266,7 +2266,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-kirlia-3-118",
"id": "westmarch-kirlia-3-117",
"level": "20-25",
"pokemon": "kirlia",
"presets": [
@@ -2289,7 +2289,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-klink-2-122",
"id": "westmarch-klink-2-121",
"level": "15-25",
"pokemon": "klink",
"presets": [
@@ -2392,7 +2392,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-lillipup-1-80",
"id": "westmarch-lillipup-1-79",
"level": "15-25",
"pokemon": "lillipup",
"presets": [
@@ -2421,7 +2421,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-lillipup-2-81",
"id": "westmarch-lillipup-2-80",
"level": "15-25",
"pokemon": "lillipup",
"presets": [
@@ -2441,7 +2441,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-maschiff-1-97",
"id": "westmarch-maschiff-1-96",
"level": "15-25",
"pokemon": "maschiff",
"presets": [
@@ -2465,7 +2465,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-maschiff-2-98",
"id": "westmarch-maschiff-2-97",
"level": "15-25",
"pokemon": "maschiff",
"presets": [
@@ -2489,7 +2489,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-maschiff-3-99",
"id": "westmarch-maschiff-3-98",
"level": "15-25",
"pokemon": "maschiff",
"presets": [
@@ -2635,7 +2635,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-milcery-1-55",
"id": "westmarch-milcery-1-54",
"level": "15-25",
"pokemon": "milcery",
"spawnablePositionType": "grounded",
@@ -2667,7 +2667,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-milcery-2-56",
"id": "westmarch-milcery-2-55",
"level": "15-25",
"pokemon": "milcery",
"presets": [
@@ -2702,7 +2702,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-milcery-3-57",
"id": "westmarch-milcery-3-56",
"level": "15-25",
"pokemon": "milcery",
"presets": [
@@ -2733,7 +2733,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-mimejr-1-119",
"id": "westmarch-mimejr-1-118",
"level": "15-25",
"pokemon": "mimejr",
"presets": [
@@ -2762,7 +2762,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-mimejr-2-120",
"id": "westmarch-mimejr-2-119",
"level": "15-25",
"pokemon": "mimejr",
"presets": [
@@ -2827,6 +2827,32 @@
"multiplier": 1.25
}
},
{
"anticondition": {
"biomes": [
"#cobblemon:is_deep_dark",
"minecraft:sulfur_caves"
]
},
"bucket": "uncommon",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 7,
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-nosepass-1-126",
"level": "15-25",
"pokemon": "nosepass",
"presets": [
"natural"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 55.2
},
{
"bucket": "common",
"condition": {
@@ -2871,7 +2897,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-onix-1-103",
"id": "westmarch-onix-1-102",
"level": "15-25",
"pokemon": "onix",
"presets": [
@@ -3080,7 +3106,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-pinsir-2-74",
"id": "westmarch-pinsir-2-73",
"level": "25-25",
"pokemon": "pinsir",
"presets": [
@@ -3109,7 +3135,7 @@
"timeRange": "night",
"zone": "westmarch"
},
"id": "westmarch-pumpkaboo-1-50",
"id": "westmarch-pumpkaboo-1-49",
"level": "15-25",
"pokemon": "pumpkaboo",
"presets": [
@@ -3136,7 +3162,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-ralts-2-115",
"id": "westmarch-ralts-2-114",
"level": "15-20",
"pokemon": "ralts",
"presets": [
@@ -3161,7 +3187,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-ralts-3-116",
"id": "westmarch-ralts-3-115",
"level": "15-20",
"pokemon": "ralts",
"presets": [
@@ -3187,7 +3213,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-roggenrola-1-111",
"id": "westmarch-roggenrola-1-110",
"level": "15-25",
"pokemon": "roggenrola",
"presets": [
@@ -3211,7 +3237,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-rolycoly-1-107",
"id": "westmarch-rolycoly-1-106",
"level": "15-24",
"pokemon": "rolycoly",
"presets": [
@@ -3340,32 +3366,6 @@
"type": "pokemon",
"weight": 90.0
},
{
"bucket": "rare",
"condition": {
"biomes": [
"#cobblemon:is_overworld"
],
"maxSkyLight": 15,
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-solosis-1-45",
"level": "15-25",
"pokemon": "solosis",
"presets": [
"natural"
],
"spawnablePositionType": "grounded",
"type": "pokemon",
"weight": 12.0,
"weightMultiplier": {
"condition": {
"isPokeSnack": true
},
"multiplier": 1.25
}
},
{
"anticondition": {
"biomes": [
@@ -3541,7 +3541,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-tentacool-2-109",
"id": "westmarch-tentacool-2-108",
"level": "15-25",
"pokemon": "tentacool",
"presets": [
@@ -3580,7 +3580,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-tentacool-5-110",
"id": "westmarch-tentacool-5-109",
"level": "15-25",
"pokemon": "tentacool",
"spawnablePositionType": "fishing",
@@ -3665,7 +3665,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-timburr-1-93",
"id": "westmarch-timburr-1-92",
"level": "15-25",
"pokemon": "timburr",
"presets": [
@@ -3709,7 +3709,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-timburr-2-94",
"id": "westmarch-timburr-2-93",
"level": "15-25",
"pokemon": "timburr",
"presets": [
@@ -3744,7 +3744,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-toxel-1-91",
"id": "westmarch-toxel-1-90",
"level": "15-24",
"pokemon": "toxel",
"presets": [
@@ -3765,7 +3765,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-toxel-2-92",
"id": "westmarch-toxel-2-91",
"level": "15-24",
"pokemon": "toxel",
"presets": [
@@ -3804,7 +3804,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-tynamo-2-113",
"id": "westmarch-tynamo-2-112",
"level": "15-25",
"pokemon": "tynamo",
"presets": [
@@ -3829,7 +3829,7 @@
"minSkyLight": 0,
"zone": "westmarch"
},
"id": "westmarch-tynamo-5-114",
"id": "westmarch-tynamo-5-113",
"level": "15-25",
"pokemon": "tynamo",
"spawnablePositionType": "fishing",
@@ -3856,7 +3856,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-varoom-2-90",
"id": "westmarch-varoom-2-89",
"level": "15-25",
"pokemon": "varoom",
"spawnablePositionType": "grounded",
@@ -3884,7 +3884,7 @@
"minSkyLight": 8,
"zone": "westmarch"
},
"id": "westmarch-yamper-1-46",
"id": "westmarch-yamper-1-45",
"level": "15-25",
"pokemon": "yamper",
"presets": [
@@ -3919,7 +3919,7 @@
],
"zone": "westmarch"
},
"id": "westmarch-yamper-2-47",
"id": "westmarch-yamper-2-46",
"level": "15-25",
"pokemon": "yamper",
"presets": [
+3
View File
@@ -28,6 +28,9 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue
| Guardian drops | Button Isle 10 Poké Balls + 4 Potions; Southwold 6 Great Balls + 4 Exp. Candy S; Westmarch and Jungle Mire Waders + 4 Pecha Berries + 2 Exp. Candy M; Mire and Highlands 3 Icy Rocks + 4 Super Potions; Sunscorch 3 Heat Rocks + 2 Exp. Candy L; Frostpeak and Deep Dark 3 Icy Rocks + 2 Exp. Candy L; Deep Sea Mystic Water + 3 Exp. Candy M | Placeholder | `world/zones.json` → `guardian.drops` | 3 rocks make one full fur or hide set |
| Mire poison | Poison I for 7 s, renewed every 5 s while in the Mire without Mire Waders | Placeholder | `datapacks/core/data/cobblesurvival/zone_hazards/mire.json` | Vanilla Poison stops at half a heart |
| Level pressure | full experience up to 5 levels above the zone's band, then 10 % less per level, at least 10 % (Exp. Candy and commands exempt) | Placeholder | `world/zones.json` → `level_pressure` | E.g. on Button Isle (up to Lv 10): Lv 15 full, Lv 20 half, Lv 24+ a tenth |
| Strong flyer | ridable through the air with top speed ≥ 60 or top stamina ≥ 85 (Cobblemon ride stats) | Placeholder | `tools/zone_spawns.py` (`STRONG_FLYER_*`) | 29 species |
| High zone for strong flyers | band starts at Lv 30 or more (Sunscorch, Frostpeak, Deep Sea, Deep Dark, Basalt Furnace) | Placeholder | `tools/zone_spawns.py` (`HIGH_ZONE_LEVEL`) | |
| Ride stats (speed, stamina, ...) | Cobblemon's own | To tune after play-testing | species `riding` via `species_additions` | |
| Healing while sleeping | off (`healPercent` 0) | Decided (roadmap) | `config/cobblemon/main.json` | |
| Loot container refresh | 1 hour (72,000 ticks of game time) after first opened, all containers | Decided (Adrian, 2026-10-29) | `config/lootr-common.toml` | Tiering by structure/biome later |
| Gamerules in the template | `doMobSpawning false` | Decided (Adrian, 2026-10-28; may be reverted later) | `world/world.json` → `gamerules` | Pokémon spawning is Cobblemon's own `doPokemonSpawning` |
+11 -1
View File
@@ -23,7 +23,16 @@ Open `build/zone-map.png` (the island coloured by zone) and read the draft in `d
- **Soft level pressure** (step 6). Pokémon far above a zone's band learn less there. Automated: `level_pressure_cuts_xp`.
Still to come: flyers.
- **Flyers** (step 7). Strong flyers only spawn in zones from Lv 30 up; checked by `tools/zone_spawns.py`. Ride stats are still Cobblemon's.
All Phase 3 steps are in. Done-when from the roadmap: the spawn survey shows only each zone's species and levels (`spawn_survey`), and the cold zone hurts an unprotected player but not one in the fur set (`cold_needs_fur`).
## Ask Adrian: approve Phase 3 before Phase 4
- Zone species lists (`docs/zone-species.md`), guardians and their drops, level bands: placeholders to approve or change.
- Hazard numbers: Frostpeak about 1 min bare / 14 min in fur at noon; Sunscorch about 2 / 25 min; the Mire's Poison every 5 s without waders.
- Level pressure: 10 % less experience per level beyond 5 above the band, at least 10 %.
- Flyers: ride stats unchanged until play-tested; Salamence never wild, Aerodactyl fossil-only.
## In-game
@@ -36,3 +45,4 @@ Still to come: flyers.
- [ ] **Guardians:** `/cobblesurvival guardians` (operator) lists each zone's guardian and spot. Walk there: a big Pokémon appears, can't be caught, and beating it puts its drops in your inventory with a gold message. It's gone for 5 hours of play.
- [ ] **Mire:** walk into the Mangrove Mire: a green warning, then Poison keeps coming back. With Mire Waders on (from the Westmarch or Jungle guardian) nothing happens.
- [ ] **Level pressure:** bring a Lv 30 Pokémon to Button Isle and win a battle: it gains only a sliver of experience, while a Lv 10 one gains the full amount.
- [ ] **Flyers:** no Pokémon you can fly on turns up wild before Sunscorch or Frostpeak; mounting any flyer you own still works everywhere.
+2
View File
@@ -113,6 +113,8 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung
**Soft level pressure** (Phase 3, step 6; no hard level caps): a Pokémon more than 5 levels above the band of the zone its trainer is in gets 10 % less experience per extra level, down to 10 % (`zone/LevelPressure.kt`, values in `world/zones.json` → `level_pressure`). It counts battle experience and anything else except Exp. Candy and commands. The roadmap also offered a disobedience chance; experience alone is gentler and Cobblemon has nothing to build disobedience on. Tested: `level_pressure_cuts_xp`.
**Flyers** (Phase 3, step 7): strong flyers only spawn in high-level zones. A species you can ride through the air with a top flying speed of 60 or a top stamina of 85 (Cobblemon's ride stats) never spawns in a zone whose band starts below Lv 30; its weaker pre-evolutions still do, and a line that starts as a strong flyer is only placed in such zones (`tools/zone_spawns.py`, which refuses to write pools that break this). So Drampa lives in Sunscorch, Togekiss, Staraptor and Braviary in Frostpeak, Charizard in the Basalt Furnace; Salamence never spawns (Bagon and Shelgon stay in the Dripstone caves), and Aerodactyl only comes from fossils. Ride stats stay Cobblemon's for now: they can be overridden per species with a `species_additions` file replacing `riding`, best tuned after play-testing how far a flyer takes you on a 3 km island. Nothing blocks mounting.
**Alpha guardians** (Phase 3, step 4; Adrian, 2026-10-29: fixed spots, back 5 hours after being beaten):
- One per zone except the Shallows, Lush Caves and Dripstone; the Basalt Furnace gets its boss in Phase 7. Each stands at its zone's sample point (deep inside the zone; a cave floor for the Deep Dark) and only appears while a player is within 96 blocks; it wanders no further than 24 blocks.
- The guardian is the strongest Pokémon that spawns walking (or, at sea, swimming) in its zone, five levels above the band, half again as big, and uncatchable: Pachirisu (Button Isle), Sigilyph (Southwold), Carbink (Westmarch), Tangrowth (Jungle), Arcanine (Mire), Cinderace (Highlands), Delphox (Sunscorch), Tyranitar (Frostpeak), Kingdra (Deep Sea), Dusknoir (Deep Dark). `world/zones.json` → `guardian.species` overrides the pick.
+10 -10
View File
@@ -10,17 +10,17 @@ Bidoof, Bonsly, Caterpie (Butterfree, Caterpie, Metapod), Combee, Diglett, Ditto
Axew (Fraxure, Haxorus), Basculin (Basculegion, Basculin), Budew (Roselia, Roserade), Cherubi (Cherrim), Chespin (Chesnaught, Quilladin), Chikorita (Bayleef, Meganium), Chimchar (Infernape, Monferno), Cryogonal, Cufant (Copperajah), Delibird, Duraludon (Archaludon, Duraludon), Elekid (Electabuzz, Electivire), Gossifleur (Eldegoss), Larvitar (Pupitar, Tyranitar), Machop (Machamp, Machoke), Makuhita (Hariyama), Mankey (Annihilape, Primeape), Mienfoo (Mienshao), Minior, Rhyhorn (Rhydon, Rhyperior), Riolu (Lucario), Rockruff (Lycanroc), Rowlet (Dartrix, Decidueye), Rufflet (Braviary), Salandit, Sawk, Skiddo (Gogoat), Smoochum (Jynx), Sneasel (Sneasel, Sneasler), Snom (Frosmoth), Snorunt (Froslass, Glalie), Snover (Abomasnow), Spinda, Spoink (Grumpig), Sprigatito (Floragato, Meowscarada), Spritzee (Aromatisse), Starly (Staraptor), Throh, Togedemaru, Togepi (Togekiss, Togetic), Tyrogue (Hitmonchan, Hitmonlee, Hitmontop), Vanillite (Vanillish, Vanilluxe), Wooloo (Dubwool)
## Sunscorch (Lv 30–45, 32 lines)
## Sunscorch (Lv 30–45, 33 lines)
Bramblin (Brambleghast), Cacnea (Cacnea, Cacturne), Capsakid (Capsakid, Scovillain), Cubone (Cubone, Marowak), Dwebble (Crustle, Dwebble), Ekans (Arbok), Falinks, Fennekin (Braixen, Delphox, Fennekin), Flittle (Espathra), Fuecoco (Crocalor, Fuecoco, Skeledirge), Helioptile (Heliolisk), Hippopotas (Hippopotas, Hippowdon), Klawf, Larvesta, Maractus, Nacli (Garganacl, Naclstack), Numel (Camerupt, Numel), Pawniard, Phanpy (Donphan, Phanpy), Poltchageist (Poltchageist, Sinistcha), Rellor (Rabsca), Sandile (Krokorok, Krookodile), Sandshrew (Sandshrew, Sandslash), Scraggy (Scrafty, Scraggy), Shinx (Luxio, Luxray), Silicobra (Sandaconda, Silicobra), Skarmory, Skorupi (Drapion, Skorupi), Spearow (Fearow), Totodile (Croconaw, Feraligatr, Totodile), Trapinch (Flygon, Vibrava), Tympole (Palpitoad, Seismitoad)
Bramblin (Brambleghast), Cacnea (Cacnea, Cacturne), Capsakid (Capsakid, Scovillain), Cubone (Cubone, Marowak), Drampa, Dwebble (Crustle, Dwebble), Ekans (Arbok), Falinks, Fennekin (Braixen, Delphox, Fennekin), Flittle (Espathra), Fuecoco (Crocalor, Fuecoco, Skeledirge), Helioptile (Heliolisk), Hippopotas (Hippopotas, Hippowdon), Klawf, Larvesta, Maractus, Nacli (Garganacl, Naclstack), Numel (Camerupt, Numel), Pawniard, Phanpy (Donphan, Phanpy), Poltchageist (Poltchageist, Sinistcha), Rellor (Rabsca), Sandile (Krokorok, Krookodile), Sandshrew (Sandshrew, Sandslash), Scraggy (Scrafty, Scraggy), Shinx (Luxio, Luxray), Silicobra (Sandaconda, Silicobra), Skarmory, Skorupi (Drapion, Skorupi), Spearow (Fearow), Totodile (Croconaw, Feraligatr, Totodile), Trapinch (Flygon, Vibrava), Tympole (Palpitoad, Seismitoad)
## Mangrove Mire (Lv 25–38, 29 lines)
## Mangrove Mire (Lv 25–38, 26 lines)
Applin (Appletun, Applin, Dipplin, Flapple, Hydrapple), Arrokuda (Arrokuda, Barraskewda), Croagunk (Croagunk, Toxicroak), Deino, Dondozo, Dratini (Dragonair, Dratini), Ducklett (Ducklett, Swanna), Flabébé (Flabébé, Floette, Florges), Flamigo, Froakie (Froakie, Frogadier, Greninja), Gible (Gabite, Gible), Goomy, Growlithe (Arcanine, Growlithe), Happiny (Chansey), Illumise, Karrablast (Escavalier, Karrablast), Magikarp (Gyarados), Misdreavus, Mudkip (Marshtomp, Mudkip, Swampert), Munchlax (Munchlax, Snorlax), Shelmet (Accelgor, Shelmet), Slowpoke, Sobble (Drizzile, Inteleon, Sobble), Surskit (Masquerain, Surskit), Tadbulb (Bellibolt, Tadbulb), Tatsugiri, Teddiursa (Teddiursa, Ursaring), Volbeat, Yanma (Yanma, Yanmega)
Applin (Appletun, Applin, Dipplin, Flapple, Hydrapple), Arrokuda (Arrokuda, Barraskewda), Croagunk (Croagunk, Toxicroak), Deino, Dondozo, Dratini (Dragonair, Dratini), Ducklett (Ducklett, Swanna), Flabébé (Flabébé, Floette, Florges), Flamigo, Froakie (Froakie, Frogadier, Greninja), Gible (Gabite, Gible), Goomy, Growlithe (Arcanine, Growlithe), Illumise, Karrablast (Escavalier, Karrablast), Misdreavus, Mudkip (Marshtomp, Mudkip, Swampert), Shelmet (Accelgor, Shelmet), Slowpoke, Sobble (Drizzile, Inteleon, Sobble), Surskit (Masquerain, Surskit), Tadbulb (Bellibolt, Tadbulb), Tatsugiri, Teddiursa (Teddiursa, Ursaring), Volbeat, Yanma (Yanma, Yanmega)
## Verdant Jungle (Lv 18–30, 34 lines)
## Verdant Jungle (Lv 18–30, 35 lines)
Aipom, Bellsprout (Bellsprout, Weepinbell), Bounsweet (Bounsweet, Steenee, Tsareena), Bulbasaur (Bulbasaur, Ivysaur), Chatot, Darumaka, Exeggcute (Exeggcute, Exeggutor), Fomantis, Glimmet, Grookey (Grookey, Thwackey), Jangmo-o, Kecleon, Litten (Litten, Torracat), Magnemite (Magnemite, Magneton), Natu (Natu, Xatu), Noibat, Nosepass, Panpour (Panpour, Simipour), Pansage (Pansage, Simisage), Pansear (Pansear, Simisear), Pikipek (Pikipek, Toucannon, Trumbeak), Porygon, Shroodle (Grafaiai, Shroodle), Slakoth (Slakoth, Vigoroth), Snivy (Servine, Snivy), Stunfisk, Tangela (Tangela, Tangrowth), Treecko (Grovyle, Treecko), Tropius, Unown, Venipede (Scolipede, Venipede, Whirlipede), Wimpod (Golisopod, Wimpod), Woobat (Swoobat, Woobat), Zubat (Golbat, Zubat)
Aipom, Bellsprout (Bellsprout, Weepinbell), Bounsweet (Bounsweet, Steenee, Tsareena), Bulbasaur (Bulbasaur, Ivysaur), Chatot, Darumaka, Exeggcute (Exeggcute, Exeggutor), Fomantis, Glimmet, Grookey (Grookey, Thwackey), Happiny (Chansey, Happiny), Jangmo-o, Kecleon, Litten (Litten, Torracat), Magikarp (Gyarados, Magikarp), Magnemite (Magnemite, Magneton), Munchlax, Natu (Natu, Xatu), Noibat, Panpour (Panpour, Simipour), Pansage (Pansage, Simisage), Pansear (Pansear, Simisear), Pikipek (Pikipek, Toucannon, Trumbeak), Porygon, Shroodle (Grafaiai, Shroodle), Slakoth (Slakoth, Vigoroth), Snivy (Servine, Snivy), Stunfisk, Tangela (Tangela, Tangrowth), Treecko (Grovyle, Treecko), Tropius, Unown, Wimpod (Golisopod, Wimpod), Woobat (Swoobat, Woobat), Zubat (Golbat, Zubat)
## Highland Meadows (Lv 25–35, 39 lines)
@@ -28,11 +28,11 @@ Abra (Abra, Alakazam, Kadabra), Bouffalant, Buizel (Buizel, Floatzel), Chewtle (
## Westmarch (Lv 15–25, 49 lines)
Baltoy, Bronzor, Buneary, Carbink, Corphish, Corsola, Deerling, Dewpider (Araquanid, Dewpider), Drifloon, Drilbur, Dunsparce, Eevee, Farfetch'd, Fletchling (Fletchinder, Fletchling), Gastly (Gastly, Haunter), Geodude (Geodude, Graveler), Grimer, Grubbin (Charjabug, Grubbin), Hawlucha, Heracross, Honedge, Klink, Lillipup (Herdier, Lillipup), Maschiff, Milcery (Alcremie, Milcery), Mime Jr., Nickit (Nickit, Thievul), Onix, Petilil (Lilligant, Petilil), Phantump, Pichu (Pichu, Pikachu), Pinsir, Pumpkaboo, Ralts (Kirlia, Ralts), Roggenrola (Boldore, Roggenrola), Rolycoly (Carkol, Rolycoly), Scyther, Seedot (Nuzleaf, Seedot), Shroomish (Breloom, Shroomish), Skwovet (Greedent, Skwovet), Solosis, Stunky, Tandemaus (Maushold, Tandemaus), Tentacool, Timburr (Gurdurr, Timburr), Toxel, Tynamo, Varoom, Yamper (Boltund, Yamper)
Baltoy, Bronzor, Buneary, Carbink, Corphish, Corsola, Deerling, Dewpider (Araquanid, Dewpider), Drifloon, Drilbur, Dunsparce, Eevee, Farfetch'd, Fletchling (Fletchinder, Fletchling), Gastly (Gastly, Haunter), Geodude (Geodude, Graveler), Grimer, Grubbin (Charjabug, Grubbin), Hawlucha, Heracross, Honedge, Klink, Lillipup (Herdier, Lillipup), Maschiff, Milcery (Alcremie, Milcery), Mime Jr., Nickit (Nickit, Thievul), Nosepass, Onix, Petilil (Lilligant, Petilil), Phantump, Pichu (Pichu, Pikachu), Pinsir, Pumpkaboo, Ralts (Kirlia, Ralts), Roggenrola (Boldore, Roggenrola), Rolycoly (Carkol, Rolycoly), Scyther, Seedot (Nuzleaf, Seedot), Shroomish (Breloom, Shroomish), Skwovet (Greedent, Skwovet), Stunky, Tandemaus (Maushold, Tandemaus), Tentacool, Timburr (Gurdurr, Timburr), Toxel, Tynamo, Varoom, Yamper (Boltund, Yamper)
## Southwold (Lv 8–18, 50 lines)
Absol, Audino, Azurill (Azumarill, Azurill, Marill), Barboach, Bunnelby, Burmy, Chingling, Comfey, Cutiefly, Drampa, Drowzee, Druddigon, Elgyem, Espurr, Fidough, Furfrou, Glameow, Goldeen, Indeedee, Joltik, Klefki, Koffing, Lotad (Lombre, Lotad), Meowth, Minccino, Minun, Morpeko, Munna, Orthworm, Patrat, Pidove, Plusle, Purrloin, Relicanth, Sentret (Furret, Sentret), Shuppet, Sigilyph, Slugma, Snubbull, Squawkabilly, Swablu, Swirlix, Taillow, Trubbish, Venonat, Voltorb, Whismur, Yamask, Yungoos, Zigzagoon
Absol, Audino, Azurill (Azumarill, Azurill, Marill), Barboach, Bunnelby, Burmy, Chingling, Comfey, Cutiefly, Drowzee, Druddigon, Elgyem, Espurr, Fidough, Furfrou, Glameow, Goldeen, Indeedee, Joltik, Klefki, Koffing, Lotad (Lombre, Lotad), Meowth, Minccino, Minun, Morpeko, Munna, Orthworm, Patrat, Pidove, Plusle, Purrloin, Relicanth, Sentret (Furret, Sentret), Shuppet, Sigilyph, Slugma, Snubbull, Solosis, Squawkabilly, Swablu, Swirlix, Taillow, Trubbish, Venonat, Voltorb, Whismur, Yamask, Yungoos, Zigzagoon
## Shallows (Lv 5–20, 21 lines)
@@ -44,7 +44,7 @@ Binacle (Barbaracle, Binacle), Clamperl (Clamperl, Gorebyss, Huntail), Clauncher
## Lush Caves (Lv 12–28, 16 lines)
Aerodactyl, Amaura, Anorith, Archen, Carnivine, Cranidos, Ferroseed, Kabuto, Lileep, Morelull (Morelull, Shiinotic), Omanyte, Paras (Paras, Parasect), Shieldon, Shuckle, Tirtouga, Tyrunt
Amaura, Anorith, Archen, Carnivine, Cranidos, Ferroseed, Kabuto, Lileep, Morelull (Morelull, Shiinotic), Omanyte, Paras (Paras, Parasect), Shieldon, Shuckle, Tirtouga, Tyrunt, Venipede (Venipede, Whirlipede)
## Dripstone Depths (Lv 22–38, 5 lines)
@@ -70,7 +70,7 @@ One per zone at its sample point, uncatchable, five levels above the band; it re
| Mangrove Mire | Arcanine | 43 | 3× icy_rock, 4× super_potion |
| Verdant Jungle | Tangrowth | 35 | 1× mire_waders, 4× pecha_berry, 2× exp_candy_m |
| Highland Meadows | Cinderace | 40 | 3× icy_rock, 4× super_potion |
| Westmarch | Pinsir | 30 | 1× mire_waders, 4× pecha_berry, 2× exp_candy_m |
| Westmarch | Scyther | 30 | 1× mire_waders, 4× pecha_berry, 2× exp_candy_m |
| Southwold | Sigilyph | 23 | 6× great_ball, 4× exp_candy_s |
| Deep Sea | Kingdra | 55 | 1× mystic_water, 3× exp_candy_m |
| Deep Dark | Dusknoir | 65 | 3× icy_rock, 2× exp_candy_l |
+47 -13
View File
@@ -21,7 +21,8 @@ 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.
3. world/zones.json → "species" pins a line to a zone by hand: {"pikachu": "southwold"}.
4. In cave zones, sky-light minimums, "can see sky" and the "natural" ground preset are dropped.
5. Each zone with a "guardian" gets datapacks/core/data/cobblesurvival/guardians/<zone>.json: the
5. Strong flyers (STRONG_FLYER_*) only spawn in zones whose band starts at HIGH_ZONE_LEVEL or more.
6. Each zone with a "guardian" gets datapacks/core/data/cobblesurvival/guardians/<zone>.json: the
strongest Pokémon spawning in the zone (or "species"), uncatchable, half again as big, five levels
above the band, with the zone's boss drops and world/zones.json → guardian_respawn_hours.
@@ -54,6 +55,13 @@ MIN_CELLS = 5 # a zone "has" a biome when at least this many grid cells of it l
# tags): its biomes say nothing about a home, so it only goes to a land zone, by strength. Its cave and
# water entries still spawn underground and in the rivers of that zone.
ALL_ROUNDER = 0.8
# Roadmap Phase 3: strong flyers only spawn in high-level zones. A species you can ride through the air with a top
# flying speed or stamina this high never spawns in a zone whose band starts below HIGH_ZONE_LEVEL (its weaker
# pre-evolutions still do), and a line that starts as one is placed in such a zone only; if none fits its habitat,
# it doesn't spawn in the wild.
STRONG_FLYER_SPEED = 60
STRONG_FLYER_STAMINA = 85
HIGH_ZONE_LEVEL = 30
def cobblemon_jar():
@@ -98,16 +106,23 @@ def zone_biomes(plan, layout, preview):
return shares
def base_stat_totals(jar):
"""{species id: base-stat total} from Cobblemon's species files."""
totals = {}
def species_data(jar):
"""({species id: base-stat total}, {species ids that are strong flyers}) from Cobblemon's species files."""
totals, flyers = {}, set()
with zipfile.ZipFile(jar) as z:
for name in z.namelist():
m = re.fullmatch(r"data/cobblemon/species/[^/]+/([^/]+)\.json", name)
if m:
stats = json.loads(z.read(name)).get("baseStats", {})
totals[f"cobblemon:{m[1]}"] = sum(stats.values())
return totals
if not m:
continue
data = json.loads(z.read(name))
totals[f"cobblemon:{m[1]}"] = sum(data.get("baseStats", {}).values())
air = ((data.get("riding") or {}).get("behaviours") or {}).get("AIR") or {}
stats = air.get("stats", {})
def top(stat):
return int(str(stats.get(stat, "0")).split("-")[-1])
if air and (top("SPEED") >= STRONG_FLYER_SPEED or top("STAMINA") >= STRONG_FLYER_STAMINA):
flyers.add(f"cobblemon:{m[1]}")
return totals, flyers
def load_before(zone, room, stretch, target):
@@ -132,7 +147,7 @@ def main():
species = guide["species"]
jar = cobblemon_jar()
entries = load_entries(jar)
bst = base_stat_totals(jar)
bst, strong_flyers = species_data(jar)
zones = {z["id"]: z for z in plan["zones"]} | {c["id"]: c for c in plan["caves"]}
shares = zone_biomes(plan, layout, preview)
@@ -161,6 +176,10 @@ def main():
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()}
flying_lines = {root for root in lines if root in strong_flyers}
def allowed(root, zid):
return root not in flying_lines or zones[zid]["levels"][0] >= HIGH_ZONE_LEVEL
wanted = {zid: z.get("lines", 20) for zid, z in zones.items()}
scale = len(lines) / sum(wanted.values())
target = {zid: n * scale for zid, n in wanted.items()}
@@ -191,7 +210,7 @@ def main():
fit = 1 - abs(rank[root] - tier[zid])
return habitat * specific ** 0.5 * fit ** 2 / (1 + load[zid] / target[zid])
candidates = [zid for zid in zones if line_biomes & biomes_of[zid]]
candidates = [zid for zid in zones if line_biomes & biomes_of[zid] and allowed(root, zid)]
if candidates:
home[root] = max(candidates, key=score)
load[home[root]] += 1
@@ -206,14 +225,21 @@ def main():
for root in sorted(all_rounders, key=lambda r: rank[r]):
while load[current] >= load_before(current, room, stretch, target) and current != by_tier[-1]:
current = next(zone_iter)
home[root] = current
load[current] += 1
# A strong flyer skips ahead to the first high zone.
home[root] = current if allowed(root, current) else next((z for z in by_tier if allowed(root, z)), None)
if home[root] is None:
del home[root]
continue
load[home[root]] += 1
pools = collections.defaultdict(list)
report = collections.defaultdict(list)
for root, zid in home.items():
lo, hi = zones[zid]["levels"]
usable = [(e, b, m, lv) for e, b, m, lv in lines[root] if b & biomes_of[zid]]
high = zones[zid]["levels"][0] >= HIGH_ZONE_LEVEL
usable = [(e, b, m, lv) for e, b, m, lv in lines[root] if b & biomes_of[zid] and (high or m not in strong_flyers)]
if not usable:
continue
fitting = [(e, m, max(lv[0], lo), min(lv[1], hi)) for e, b, m, lv in usable if lv[0] <= hi and lv[1] >= lo]
if not fitting:
# No stage reaches the band: the closest stage spawns across all of it.
@@ -238,6 +264,11 @@ def main():
names = sorted({species[m]["name"] for _, m, _, _ in fitting})
report[zid].append((species.get(root, {}).get("name", root), names))
low_flyers = [(zid, s["pokemon"]) for zid, spawns in pools.items() for s in spawns
if zones[zid]["levels"][0] < HIGH_ZONE_LEVEL and f"cobblemon:{s['pokemon'].split()[0].lower()}" in strong_flyers]
if low_flyers:
sys.exit(f"strong flyers would spawn below Lv {HIGH_ZONE_LEVEL}: {low_flyers[:5]}")
OUT.mkdir(parents=True, exist_ok=True)
for old in OUT.glob("*.json"):
old.unlink()
@@ -292,6 +323,9 @@ def main():
REPORT.write_text("\n".join(lines_out) + "\n")
unplaced = [r for r in lines if r not in home]
grounded = sorted(species.get(r, {}).get("name", r) for r in unplaced if r in flying_lines)
if grounded:
print(f"strong flyers kept out of the wild (no high zone fits their habitat): {', '.join(grounded)}")
for zid, zone in zones.items():
print(f" {zone['name']:18s} {len(report.get(zid, [])):3d} lines {len(pools.get(zid, [])):4d} spawn entries")
print(f"{len(home)} lines placed, {len(unplaced)} with no matching zone; wrote {OUT.relative_to(ROOT)} and {REPORT.relative_to(ROOT)}")