#!/usr/bin/env python3 """Make the machine test world (Phase 6; Adrian, 2026-11-02): a superflat creative world, cheats on, with every machine built by `/cobblesurvival machines showcase` (working with a Pokémon inside, empty, and the bare core), no wild Pokémon spawning and fixed daytime. It lands in build/machine-world; with --prism it is also copied into the Prism instance as the save "Machine Test (Phase 6)", replacing an older copy. Needs the test server (tools/build.py first; the EULA accepted as for the other tools). Usage: tools/make_machine_world.py [--prism] [--instance NAME] """ import argparse import shutil import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) import nbtfile # noqa: E402 from make_world import SKIP # noqa: E402 from mcserver import BUILD, SERVER, Server, eula_accepted, prepare, scan_log # noqa: E402 from prism_instance import PRISM_DIRS # noqa: E402 LEVEL = "machines" NAME = "Machine Test (Phase 6)" OUT = BUILD / "machine-world" FLAT = ('{"layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:stone","height":3},' '{"block":"minecraft:grass_block","height":1}],"biome":"minecraft:plains"}') # Ground is y -60; the showcase starts at the first air above it. ORIGIN = (0, -59, 0) SPAWN = (24, -59, 8) COMMANDS = [ "gamerule doPokemonSpawning false", "gamerule doDaylightCycle false", "gamerule doWeatherCycle false", "time set day", f"setworldspawn {SPAWN[0]} {SPAWN[1]} {SPAWN[2]}", f"execute positioned {ORIGIN[0]} {ORIGIN[1]} {ORIGIN[2]} run cobblesurvival machines showcase", ] def make_creative(level_dat): """Creative mode, cheats on, and a name the world list can tell apart.""" name, root = nbtfile.load(level_dat) data = root["Data"][1] data["LevelName"] = (nbtfile.STRING, NAME) data["GameType"] = (nbtfile.INT, 1) data["allowCommands"] = (nbtfile.BYTE, 1) nbtfile.save(level_dat, name, root) def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("--prism", action="store_true", help="copy the world into the Prism instance") parser.add_argument("--instance", default="Cobblemon Survival Pack (dev)") args = parser.parse_args() if not eula_accepted(): sys.exit("build/server/eula.txt does not accept the Minecraft EULA yet (see tools/selftest.py --accept-eula).") args_file = prepare() world = SERVER / LEVEL shutil.rmtree(world, ignore_errors=True) props = {"level-name": LEVEL, "level-type": "minecraft:flat", "generator-settings": FLAT, "gamemode": "creative"} with Server(args_file, props, stdout_name="machine-world-stdout.log") as server: print(f"server started in {server.wait_ready():.0f}s") for command in COMMANDS: print(f" {command}: {server.command(command).strip()}") server.command("save-all flush") server.stop() problems = scan_log(server.log) if problems: sys.exit("server log problems:\n" + "\n".join(f" - {p}" for p in problems)) shutil.rmtree(OUT, ignore_errors=True) shutil.copytree(world, OUT, ignore=SKIP) make_creative(OUT / "level.dat") print(f"machine world: {OUT.relative_to(BUILD.parent)}") if args.prism: prism = next((d for d in PRISM_DIRS if d.exists()), None) if prism is None: sys.exit("no Prism Launcher data folder found") saves = prism / "instances" / args.instance / "minecraft" / "saves" if not saves.parent.exists(): sys.exit(f"no Prism instance {args.instance!r}; run tools/prism_instance.py first") target = saves / NAME shutil.rmtree(target, ignore_errors=True) shutil.copytree(OUT, target) print(f"installed as the save {NAME!r} in {args.instance}") if __name__ == "__main__": main()