Phase 4: veins in every chunk, drops for the mobs the island lacks

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>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-30 03:36:50 +01:00
1 parent 5d275e4e14
commit 1a1fb93da8
33 files changed
+1279 -126

No files matched your search

+30 -1
View File
@@ -12,11 +12,15 @@ world/zones.json → "ores" lists the tiers. This tool writes pack/config/regene
of the cave biomes, which are zones of their own; a cave tier's veins to its cave biome. The mod checks
the area for every block and the biome at a vein's centre. One vein only for the self-tests comes
last ("selftest", a single coal block); its area lies far outside the world border, so it never
generates, and the tests place it by command.
generates, and the tests place it by command. Each tier with "showcase" also gets "<tier>_showcase", a full
radius-2 vein in the same place-only area, which tools/make_world.py places by hand near the zone's sample point.
* global.json: regenerators can't be broken by players (allow_breaking false), so nobody can remove a
vein for good; explosions don't destroy veins.
* vein_locator.json: the Vein Locator from a compass and a copper ingot (mid-game) instead of netherite.
It also writes world/vein-sources.json, the veins as item sources for the field guide (tools/fieldguide/build.py
reads it by default): what each tier's blocks drop and in which zone.
Re-run after changing the zone plan or the grid (tools/zone_layout.py) and commit the result.
Usage: tools/zone_ores.py
@@ -30,6 +34,17 @@ OUT = ROOT / "pack/config/regenerating_ore_veins"
LAYOUT = ROOT / "build/zone-layout.json"
BOTTOM, TOP = -64, 320
SELFTEST_AREA = "selftest_nowhere"
SOURCES = ROOT / "world/vein-sources.json"
# What an ore block drops, where it isn't the block itself or "<name>_ore" → "<name>".
DROPS = {"iron": "raw_iron", "copper": "raw_copper", "gold": "raw_gold", "lapis": "lapis_lazuli",
"nether_quartz": "quartz", "amethyst_block": "amethyst_block", "budding_amethyst": "amethyst_shard"}
def drop_of(block):
namespace, name = block.split(":")
base = name.removeprefix("deepslate_").removeprefix("dripstone_").removeprefix("terracotta_")
base = base.removesuffix("_ore") if base.endswith("_ore") else base
return f"{namespace}:{DROPS.get(base, base)}"
def rectangles(mask, size):
@@ -123,6 +138,10 @@ def main():
else:
sys.exit(f"ore tier {tier}: unknown zone {zone}")
low, high = spec["y"]
if spec.get("showcase"):
blocks = [(spec["stone"], 1)] if spec.get("stone") else [tuple(b) for b in spec["blocks"]]
showcase = vein(f"{tier}_showcase", blocks, spec, defaults, (0, 0), {"area_whitelist": [SELFTEST_AREA]})
veins.append({**showcase, "min_radius": 2, "max_radius": 2, "fill_factor": 0.8})
if "blocks" in spec:
veins.append(vein(tier, spec["blocks"], spec, defaults, (low, high), where))
continue
@@ -158,6 +177,16 @@ def main():
"durability": 2,
"stack_size": 64,
}, indent=2) + "\n")
names = {z["id"]: z["name"] for z in plan["zones"] + plan["caves"]}
sources = []
for tier, spec in plan["ores"].items():
blocks = [b for b, _ in spec.get("blocks", [])] + [spec[k] for k in ("stone", "deepslate") if spec.get(k)]
for item in dict.fromkeys(drop_of(b) for b in blocks):
sources.append({"item": item, "how": f"Regenerating {tier.replace('_', ' ')} vein in {names[spec['zone']]}",
"kind": "ore vein", "needs": []})
SOURCES.write_text(json.dumps({
"_comment": "Generated by tools/zone_ores.py from world/zones.json; extra item sources for the field guide.",
"sources": sources}, indent=1) + "\n")
per_zone = {}
for tier, spec in plan["ores"].items():
per_zone.setdefault(spec["zone"], []).append(tier)