aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/mapgen.py
diff options
context:
space:
mode:
Diffstat (limited to 'mapgen.py')
-rwxr-xr-xmapgen.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/mapgen.py b/mapgen.py
new file mode 100755
index 0000000..b371454
--- /dev/null
+++ b/mapgen.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+"""World generator CLI (see README.md). A world is a folder with config/, sketch/ (and optional masks/); builds go to
+its out/."""
+import argparse
+import os
+import sys
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).resolve().parent))
+
+from mapgen import config as C # noqa: E402
+from mapgen import pipeline as P # noqa: E402
+
+
+def main(argv=None, root: Path | None = None) -> int:
+ ap = argparse.ArgumentParser(prog="mapgen.py")
+ ap.add_argument("--world", help="the world's folder (its config/, sketch/, out/); default: the current folder")
+ sub = ap.add_subparsers(dest="cmd", required=True)
+ nw = sub.add_parser("new-world", help="random sketch/ + config/tectonics.toml + config/eras.toml")
+ nw.add_argument("--seed", type=int, required=True)
+ nw.add_argument("--continents", type=int, default=6)
+ nw.add_argument("--land", type=float, default=0.27, help="land share of the sketch")
+ nw.add_argument("--toward", type=float, nargs=2, metavar=("LAT", "LON"), help="gather the land toward this point")
+ nw.add_argument("--mountains", type=float, default=0.86, help="ridge threshold (lower: more ranges)")
+ nw.add_argument("--force", action="store_true")
+ for name in ("build", "check", "era", "compare"):
+ s = sub.add_parser(name)
+ s.add_argument("--res", type=int)
+ s.add_argument("--final", action="store_true")
+ s.add_argument("--low-memory", action="store_true",
+ help="slower, lower memory peak; same results (or set WORLDGEN_LOW_MEMORY=1)")
+ if name == "compare":
+ s.add_argument("--old", required=True, help="an earlier cells.npz of the same resolution")
+ if name == "era":
+ s.add_argument("name", help="an era from config/eras.toml")
+ if name == "build":
+ s.add_argument("--from", dest="start", choices=P.STAGES)
+ s.add_argument("--stop", choices=P.STAGES)
+ a = ap.parse_args(argv)
+ if a.world:
+ root = Path(a.world).resolve()
+ elif root is None:
+ root = Path.cwd()
+ try:
+ if a.cmd == "new-world":
+ from mapgen import newworld
+ newworld.make(root, a.seed, a.continents, a.land, a.toward, a.mountains, a.force)
+ return 0
+ cfg, _ = C.load(root)
+ low = bool(getattr(a, "low_memory", False)) or os.environ.get("WORLDGEN_LOW_MEMORY", "") not in ("", "0")
+ res = a.res if a.res is not None else int(cfg["build"]["res_final" if a.final else "res_dev"])
+ if a.cmd == "build":
+ ctx = P.build(root, res, a.start, a.stop, low_memory=low)
+ if a.stop is None: # every era with events, from the fresh base
+ from mapgen import eras
+ eras.build_all(root, res, base=ctx, low_memory=low)
+ return 0
+ if a.cmd == "era":
+ from mapgen import eras
+ eras.build_era(root, res, a.name, low_memory=low)
+ return 0
+ if a.cmd == "compare": # base vs an earlier build, outside the edited areas
+ from mapgen import check
+ return check.compare_report(root, res, Path(a.old))
+ from mapgen import check
+ ctx = P.build(root, res, stop="fields", log=lambda m: None)
+ return check.report(ctx)
+ except (C.ConfigError, P.StageError) as e:
+ print(f"error: {e}", file=sys.stderr)
+ return 2
+
+
+if __name__ == "__main__":
+ sys.exit(main())