diff --git a/docs/battle-map-terrain-atlas-pipeline.md b/docs/battle-map-terrain-atlas-pipeline.md index e57c59a..b096b9a 100644 --- a/docs/battle-map-terrain-atlas-pipeline.md +++ b/docs/battle-map-terrain-atlas-pipeline.md @@ -11,9 +11,16 @@ The first thirty campaign battles now use the same hand-painted tactical map pip - Roads, forests, rivers, camps, villages, cliffs, and forts should be recognizable by silhouette and texture, not by high saturation. - The grid remains subtle and embedded in the paint grade, so it helps targeting without becoming the main visual layer. +## Resolution Policy + +- Battles 1-25 keep the original 224px hand-painted tile target. +- Large maps starting at battle 26 use a 192px tile target through `LARGE_MAP_TILE_SIZE` in the generator. +- Re-evaluate the tile target before a generated map's longest edge exceeds roughly 16,384px at 192px per tile. +- Use `--tile-size` only for controlled comparisons; commit the selected production size in the map config. + ## Generator -`scripts/generate-handpaint-map-sample.py` reads terrain and unit positions from `src/game/data/scenario.ts`, then outputs a WebP map and documentation previews. +`scripts/generate-handpaint-map-sample.py` reads terrain and unit positions from `src/game/data/scenario.ts`, then outputs a WebP map and documentation previews. Map configs can set `tile_size`; otherwise the default is 224px. Example: @@ -49,6 +56,12 @@ python scripts/generate-handpaint-map-sample.py --map twenty-ninth --webp-qualit python scripts/generate-handpaint-map-sample.py --map thirtieth --webp-quality 90 ``` +Comparison example: + +```powershell +python scripts/generate-handpaint-map-sample.py --map thirtieth --tile-size 192 --out tmp\thirtieth-battle-map-192-test.webp --comparison tmp\thirtieth-battle-map-192-test-before-after.png --preview tmp\thirtieth-battle-map-192-test-preview.png --webp-quality 90 +``` + ## Current Assets - `src/assets/images/battle/first-battle-map.webp` diff --git a/docs/thirtieth-battle-map-handpaint-before-after.png b/docs/thirtieth-battle-map-handpaint-before-after.png index e33bc98..c8b959d 100644 Binary files a/docs/thirtieth-battle-map-handpaint-before-after.png and b/docs/thirtieth-battle-map-handpaint-before-after.png differ diff --git a/docs/thirtieth-battle-map-handpaint-preview.png b/docs/thirtieth-battle-map-handpaint-preview.png index c25a341..1b8f1aa 100644 Binary files a/docs/thirtieth-battle-map-handpaint-preview.png and b/docs/thirtieth-battle-map-handpaint-preview.png differ diff --git a/docs/twenty-eighth-battle-map-handpaint-before-after.png b/docs/twenty-eighth-battle-map-handpaint-before-after.png index a014eb1..5cd2bb0 100644 Binary files a/docs/twenty-eighth-battle-map-handpaint-before-after.png and b/docs/twenty-eighth-battle-map-handpaint-before-after.png differ diff --git a/docs/twenty-eighth-battle-map-handpaint-preview.png b/docs/twenty-eighth-battle-map-handpaint-preview.png index c26011c..3d90942 100644 Binary files a/docs/twenty-eighth-battle-map-handpaint-preview.png and b/docs/twenty-eighth-battle-map-handpaint-preview.png differ diff --git a/docs/twenty-ninth-battle-map-handpaint-before-after.png b/docs/twenty-ninth-battle-map-handpaint-before-after.png index dbf1e2c..13dc2f2 100644 Binary files a/docs/twenty-ninth-battle-map-handpaint-before-after.png and b/docs/twenty-ninth-battle-map-handpaint-before-after.png differ diff --git a/docs/twenty-ninth-battle-map-handpaint-preview.png b/docs/twenty-ninth-battle-map-handpaint-preview.png index 490bca6..0d5e752 100644 Binary files a/docs/twenty-ninth-battle-map-handpaint-preview.png and b/docs/twenty-ninth-battle-map-handpaint-preview.png differ diff --git a/docs/twenty-seventh-battle-map-handpaint-before-after.png b/docs/twenty-seventh-battle-map-handpaint-before-after.png index 0cbc2ae..96b81d0 100644 Binary files a/docs/twenty-seventh-battle-map-handpaint-before-after.png and b/docs/twenty-seventh-battle-map-handpaint-before-after.png differ diff --git a/docs/twenty-seventh-battle-map-handpaint-preview.png b/docs/twenty-seventh-battle-map-handpaint-preview.png index 5c6d230..fb9ebaf 100644 Binary files a/docs/twenty-seventh-battle-map-handpaint-preview.png and b/docs/twenty-seventh-battle-map-handpaint-preview.png differ diff --git a/docs/twenty-sixth-battle-map-handpaint-before-after.png b/docs/twenty-sixth-battle-map-handpaint-before-after.png index 6e67b6e..f001bb0 100644 Binary files a/docs/twenty-sixth-battle-map-handpaint-before-after.png and b/docs/twenty-sixth-battle-map-handpaint-before-after.png differ diff --git a/docs/twenty-sixth-battle-map-handpaint-preview.png b/docs/twenty-sixth-battle-map-handpaint-preview.png index 60e69a2..d03cecc 100644 Binary files a/docs/twenty-sixth-battle-map-handpaint-preview.png and b/docs/twenty-sixth-battle-map-handpaint-preview.png differ diff --git a/scripts/generate-handpaint-map-sample.py b/scripts/generate-handpaint-map-sample.py index bf6b5b6..f13d28c 100644 --- a/scripts/generate-handpaint-map-sample.py +++ b/scripts/generate-handpaint-map-sample.py @@ -15,7 +15,9 @@ SCENARIO_FILE = ROOT / "src" / "game" / "data" / "scenario.ts" BATTLE_IMAGE_DIR = ROOT / "src" / "assets" / "images" / "battle" DOCS_DIR = ROOT / "docs" -TILE = 224 +DEFAULT_TILE_SIZE = 224 +LARGE_MAP_TILE_SIZE = 192 +TILE = DEFAULT_TILE_SIZE RNG = random.Random(240704) MAP_CONFIGS = { @@ -252,6 +254,7 @@ MAP_CONFIGS = { "out": BATTLE_IMAGE_DIR / "twenty-sixth-battle-map.webp", "before": BATTLE_IMAGE_DIR / "twenty-sixth-battle-map.svg", "seed": 240954, + "tile_size": LARGE_MAP_TILE_SIZE, }, "twenty-seventh": { "slug": "twenty-seventh-battle-map", @@ -261,6 +264,7 @@ MAP_CONFIGS = { "out": BATTLE_IMAGE_DIR / "twenty-seventh-battle-map.webp", "before": BATTLE_IMAGE_DIR / "twenty-seventh-battle-map.svg", "seed": 240964, + "tile_size": LARGE_MAP_TILE_SIZE, }, "twenty-eighth": { "slug": "twenty-eighth-battle-map", @@ -270,6 +274,7 @@ MAP_CONFIGS = { "out": BATTLE_IMAGE_DIR / "twenty-eighth-battle-map.webp", "before": BATTLE_IMAGE_DIR / "twenty-eighth-battle-map.svg", "seed": 240974, + "tile_size": LARGE_MAP_TILE_SIZE, }, "twenty-ninth": { "slug": "twenty-ninth-battle-map", @@ -279,6 +284,7 @@ MAP_CONFIGS = { "out": BATTLE_IMAGE_DIR / "twenty-ninth-battle-map.webp", "before": BATTLE_IMAGE_DIR / "twenty-ninth-battle-map.svg", "seed": 240984, + "tile_size": LARGE_MAP_TILE_SIZE, }, "thirtieth": { "slug": "thirtieth-battle-map", @@ -288,6 +294,7 @@ MAP_CONFIGS = { "out": BATTLE_IMAGE_DIR / "thirtieth-battle-map.webp", "before": BATTLE_IMAGE_DIR / "thirtieth-battle-map.svg", "seed": 240994, + "tile_size": LARGE_MAP_TILE_SIZE, }, } @@ -846,8 +853,9 @@ def add_subtle_grid_and_grade(canvas: Image.Image, terrain: list[list[str]]) -> def build_map(config: dict[str, object]) -> Image.Image: - global RNG + global RNG, TILE RNG = random.Random(int(config["seed"])) + TILE = int(config.get("tile_size", DEFAULT_TILE_SIZE)) terrain = parse_battle_terrain(str(config["terrain_export"])) ally_positions_export = config["ally_positions_export"] units = parse_battle_units(str(config["units_export"]), None if ally_positions_export is None else str(ally_positions_export)) @@ -920,10 +928,15 @@ def main() -> None: parser.add_argument("--before", type=Path) parser.add_argument("--comparison", type=Path) parser.add_argument("--preview", type=Path) + parser.add_argument("--tile-size", type=int) parser.add_argument("--webp-quality", type=int, default=90) args = parser.parse_args() - config = MAP_CONFIGS[args.map] + config = dict(MAP_CONFIGS[args.map]) + if args.tile_size is not None: + if args.tile_size < 160: + raise ValueError("--tile-size must be 160 or greater") + config["tile_size"] = args.tile_size out_path = args.out or Path(config["out"]) before_path = args.before or Path(config["before"]) comparison_path = args.comparison or (DOCS_DIR / f"{config['slug']}-handpaint-before-after.png") @@ -950,6 +963,7 @@ def main() -> None: print( { "map": args.map, + "tile_size": TILE, "out": str(out_path), "size": after.size, "comparison": str(comparison_path), diff --git a/src/assets/images/battle/thirtieth-battle-map.webp b/src/assets/images/battle/thirtieth-battle-map.webp index e012c14..86bbd3a 100644 Binary files a/src/assets/images/battle/thirtieth-battle-map.webp and b/src/assets/images/battle/thirtieth-battle-map.webp differ diff --git a/src/assets/images/battle/twenty-eighth-battle-map.webp b/src/assets/images/battle/twenty-eighth-battle-map.webp index da16b85..6246b95 100644 Binary files a/src/assets/images/battle/twenty-eighth-battle-map.webp and b/src/assets/images/battle/twenty-eighth-battle-map.webp differ diff --git a/src/assets/images/battle/twenty-ninth-battle-map.webp b/src/assets/images/battle/twenty-ninth-battle-map.webp index c86768a..aa11be5 100644 Binary files a/src/assets/images/battle/twenty-ninth-battle-map.webp and b/src/assets/images/battle/twenty-ninth-battle-map.webp differ diff --git a/src/assets/images/battle/twenty-seventh-battle-map.webp b/src/assets/images/battle/twenty-seventh-battle-map.webp index c039f29..49be961 100644 Binary files a/src/assets/images/battle/twenty-seventh-battle-map.webp and b/src/assets/images/battle/twenty-seventh-battle-map.webp differ diff --git a/src/assets/images/battle/twenty-sixth-battle-map.webp b/src/assets/images/battle/twenty-sixth-battle-map.webp index c908037..e54af41 100644 Binary files a/src/assets/images/battle/twenty-sixth-battle-map.webp and b/src/assets/images/battle/twenty-sixth-battle-map.webp differ