WIP: ore nodes, catching rules, bee nest fix, smaller Deep Dark

Done and checked: surface and cave-floor ore nodes (companion mod
ore/OreNodes.kt), bigger and rarer underground veins; template with nodes
passed the world check and the island quick check (node self-tests).

Built, not yet tested: catching rules (catch rate falls with the level
gap to the trainer's strongest Pokemon, failed catch enrages, strong wild
Pokemon hunt weaker trainers; catching/, Fight or Flight config), bee
nests emptied when their bee is turned away.

In progress: the Deep Dark no longer fills the deepslate layer (split by
temperature: cold = Deep Dark, hot = basalt deltas, warm = ordinary caves;
world/biomes.json), zone layout regenerated; cave zone types added to
world/zones.json but tools/zone_spawns.py doesn't use them yet; template
not rebuilt for the new caves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-30 15:44:17 +01:00
1 parent 362d06aa4b
commit 6361636da7
29 files changed
+1733 -357

No files matched your search

+24 -50
View File
@@ -8,12 +8,11 @@
0,0 (the island plus a strip of sea; the sea corners inside the square
border generate when someone gets there).
3. In the same session: load the circle again row by row until Regenerating
Ore Veins has put veins into every chunk (it only fills a new chunk while
it is loaded, 8 a tick, and Chunky is faster), place the showcase ore veins (world/zones.json →
"ores", tiers with "showcase": one vein sticking out of the ground near
its zone's sample point, so players see what a regenerating vein looks
like), save, measure where the land ends (tools/world_report.py) and set
a square world border `border_margin` blocks outside the outermost coast.
Ore Veins has put its veins and the companion mod its ore nodes into every
chunk (both only fill a new chunk while it is loaded, a few a tick, and
Chunky is faster), save, measure where the land ends (tools/world_report.py)
and set a square world border `border_margin` blocks outside the outermost
coast.
4. Copy the world to build/world-template without player data, then run
the world checks and render the map (build/island-map.png).
@@ -36,14 +35,29 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
from mcserver import BUILD, ROOT, SERVER, Server, chunky, eula_accepted, prepare, scan_log # noqa: E402
import world_report # noqa: E402
import zone_grid # noqa: E402
from numpy import hypot as np_hypot # noqa: E402
TEMPLATE = BUILD / "world-template"
SKIP = shutil.ignore_patterns("playerdata", "advancements", "stats", "session.lock")
# A showcase sits this far from its zone's sample point (where guardians and the self-tests stand), first offset
# that is still inside the zone wins.
SHOWCASE_OFFSETS = [(16, 0), (0, 16), (-16, 0), (0, -16), (24, 24), (-24, -24)]
def border_for(world, recipe):
"""Square border around the land, `border_margin` past the outermost coast."""
data = world_report.analyse(world)
land = world_report.island_mask(data)
zs, xs = land.nonzero()
ox, oz = data["origin"]
x0, x1 = int(xs.min()) + ox, int(xs.max()) + ox + 1
z0, z1 = int(zs.min()) + oz, int(zs.max()) + oz + 1
far = float(np_hypot(xs + ox, zs + oz).max())
if far + recipe["border_margin"] > recipe["pregen_radius"]:
sys.exit(f"land reaches {far:.0f} blocks from 0,0; raise pregen_radius ({recipe['pregen_radius']}) in "
f"world/world.json to at least land + border_margin")
cx, cz = round((x0 + x1) / 2), round((z0 + z1) / 2)
size = max(x1 - x0, z1 - z0) + 2 * recipe["border_margin"]
print(f"land spans x {x0}..{x1}, z {z0}..{z1}, at most {far:.0f} blocks from 0,0; "
f"border center {cx},{cz} size {size}")
return cx, cz, size
def fill_veins(server, radius):
@@ -72,45 +86,6 @@ def fill_veins(server, radius):
return left
def place_showcases(server):
"""One hand-placed vein per showcase tier, half sunk into the ground near the zone's sample point."""
plan = json.loads((ROOT / "world/zones.json").read_text())
grid = zone_grid.load()
samples = json.loads(zone_grid.ISLAND.read_text())["samples"]
for tier, spec in plan["ores"].items():
if not spec.get("showcase"):
continue
sx, _, sz = samples[spec["zone"]]
spot = next(((sx + dx, sz + dz) for dx, dz in SHOWCASE_OFFSETS if grid.zone_at(sx + dx, sz + dz) == spec["zone"]), None)
if spot is None:
raise RuntimeError(f"no showcase spot inside {spec['zone']} near its sample point {sx},{sz}")
x, z = spot
server.command(f"forceload add {x} {z}")
reply = server.command(f"execute in minecraft:overworld positioned {x} 0 {z} positioned over world_surface "
f"positioned ~ ~-1 ~ run regenerating_ore_veins place {tier}_showcase").strip()
server.command(f"forceload remove {x} {z}")
print(f" showcase {tier} at {x},{z}: {reply[:100]}")
def border_for(world, recipe):
"""Square border around the land, `border_margin` past the outermost coast."""
data = world_report.analyse(world)
land = world_report.island_mask(data)
zs, xs = land.nonzero()
ox, oz = data["origin"]
x0, x1 = int(xs.min()) + ox, int(xs.max()) + ox + 1
z0, z1 = int(zs.min()) + oz, int(zs.max()) + oz + 1
far = float(np_hypot(xs + ox, zs + oz).max())
if far + recipe["border_margin"] > recipe["pregen_radius"]:
sys.exit(f"land reaches {far:.0f} blocks from 0,0; raise pregen_radius ({recipe['pregen_radius']}) in "
f"world/world.json to at least land + border_margin")
cx, cz = round((x0 + x1) / 2), round((z0 + z1) / 2)
size = max(x1 - x0, z1 - z0) + 2 * recipe["border_margin"]
print(f"land spans x {x0}..{x1}, z {z0}..{z1}, at most {far:.0f} blocks from 0,0; "
f"border center {cx},{cz} size {size}")
return cx, cz, size
def main():
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.parse_args()
@@ -133,7 +108,6 @@ def main():
seconds = server.pregenerate(0, 0, recipe["pregen_radius"], shape="circle")
print(f"pregeneration finished in {seconds:.0f}s")
fill_veins(server, recipe["pregen_radius"])
place_showcases(server)
server.command("save-all flush")
cx, cz, size = border_for(world, recipe)
print(f" {server.command(f'worldborder center {cx} {cz}').strip()}")