Add a map renderer
This commit is contained in:
parent
25bb565091
commit
9cdc1c48e4
3 changed files with 100 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
__pycache__
|
||||
repos
|
||||
build
|
||||
|
|
|
|||
3
justfile
3
justfile
|
|
@ -15,3 +15,6 @@ run:
|
|||
|
||||
debug:
|
||||
uv run python -m mudlib --debug
|
||||
|
||||
render:
|
||||
uv run python scripts/render_map.py
|
||||
|
|
|
|||
96
scripts/render_map.py
Normal file
96
scripts/render_map.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env python
|
||||
"""Render the full world map as an HTML page."""
|
||||
|
||||
import sys
|
||||
import tomllib
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
||||
|
||||
from mudlib.world.terrain import World
|
||||
|
||||
ROOT = Path(__file__).parent.parent
|
||||
|
||||
|
||||
def main():
|
||||
config_path = ROOT / "worlds" / "earth" / "config.toml"
|
||||
with open(config_path, "rb") as f:
|
||||
config = tomllib.load(f)
|
||||
|
||||
seed = config["world"]["seed"]
|
||||
width = config["world"]["width"]
|
||||
height = config["world"]["height"]
|
||||
name = config["world"]["name"]
|
||||
|
||||
print(f"generating {name} ({width}x{height}, seed={seed})...")
|
||||
world = World(seed=seed, width=width, height=height)
|
||||
|
||||
# encode terrain as compact string, one char per tile
|
||||
rows = ["".join(row) for row in world.terrain]
|
||||
terrain_data = "\\n".join(rows)
|
||||
|
||||
html = f"""<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{name}</title>
|
||||
<style>
|
||||
body {{
|
||||
margin: 0;
|
||||
background: #111;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}}
|
||||
canvas {{
|
||||
image-rendering: pixelated;
|
||||
max-width: 100vmin;
|
||||
max-height: 100vmin;
|
||||
width: 100vmin;
|
||||
height: 100vmin;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="map" width="{width}" height="{height}"></canvas>
|
||||
<script>
|
||||
const W = {width}, H = {height};
|
||||
const terrain = "{terrain_data}";
|
||||
const colors = {{
|
||||
'~': [34, 68, 170],
|
||||
':': [194, 178, 128],
|
||||
'.': [34, 139, 34],
|
||||
'T': [10, 95, 10],
|
||||
'^': [102, 102, 102],
|
||||
}};
|
||||
const canvas = document.getElementById('map');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const img = ctx.createImageData(W, H);
|
||||
const d = img.data;
|
||||
const rows = terrain.split('\\n');
|
||||
for (let y = 0; y < H; y++) {{
|
||||
const row = rows[y];
|
||||
for (let x = 0; x < W; x++) {{
|
||||
const c = colors[row[x]] || [255, 0, 255];
|
||||
const i = (y * W + x) * 4;
|
||||
d[i] = c[0];
|
||||
d[i+1] = c[1];
|
||||
d[i+2] = c[2];
|
||||
d[i+3] = 255;
|
||||
}}
|
||||
}}
|
||||
ctx.putImageData(img, 0, 0);
|
||||
</script>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
out_path = ROOT / "build" / "map.html"
|
||||
out_path.parent.mkdir(exist_ok=True)
|
||||
out_path.write_text(html)
|
||||
print(f"wrote {out_path}")
|
||||
webbrowser.open(f"file://{out_path.resolve()}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue