#!/usr/bin/env python3 """ šŸ”„ MIGRATE DEMO ASSETS TO PRODUCTION STRUCTURE This script moves all assets from: assets/slike/ To the proper production structure: assets/slike/liki/kai/ assets/slike/biomi/01_dolina_farm/ assets/slike/sovrazniki/zombies/ etc. Usage: python3 scripts/migrate_demo_to_production.py [--dry-run] """ import shutil import sys from pathlib import Path from collections import defaultdict # Base paths REPO_ROOT = Path("/Users/davidkotnik/repos/novafarma") DEMO_DIR = REPO_ROOT / "assets/slike" ASSETS_DIR = REPO_ROOT / "assets/images" # Target directories TARGETS = { "characters/kai": ASSETS_DIR / "characters/kai", "biomes/01_dolina_farm/terrain": ASSETS_DIR / "biomes/01_dolina_farm/terrain", "biomes/01_dolina_farm/buildings": ASSETS_DIR / "biomes/01_dolina_farm/buildings", "biomes/01_dolina_farm/props": ASSETS_DIR / "biomes/01_dolina_farm/props", "enemies/zombies": ASSETS_DIR / "enemies/zombies", "effects/water": ASSETS_DIR / "effects/water", "items/tools": ASSETS_DIR / "items/tools", "items/seeds": ASSETS_DIR / "items/seeds", "ui": ASSETS_DIR / "ui", } # Asset classification rules RULES = { # Kai (protagonist) "kai_": "characters/kai", # Zombies "zombie_": "enemies/zombies", # Terrain "grass_": "biomes/01_dolina_farm/terrain", "dirt_": "biomes/01_dolina_farm/terrain", "tilled_": "biomes/01_dolina_farm/terrain", "stone_path": "biomes/01_dolina_farm/terrain", "mud_": "biomes/01_dolina_farm/terrain", # Buildings "shack": "biomes/01_dolina_farm/buildings", "barn": "biomes/01_dolina_farm/buildings", "tent": "biomes/01_dolina_farm/buildings", "campfire": "biomes/01_dolina_farm/props", "water_well": "biomes/01_dolina_farm/buildings", "storage_chest": "biomes/01_dolina_farm/props", # Props/Environment "tree_": "biomes/01_dolina_farm/props", "oak_tree": "biomes/01_dolina_farm/props", "rock_": "biomes/01_dolina_farm/props", "bush_": "biomes/01_dolina_farm/props", "fence_": "biomes/01_dolina_farm/props", "sign_": "biomes/01_dolina_farm/props", # Effects "water_anim": "effects/water", "smoke_": "effects/particles", # Items "hoe_": "items/tools", "axe_": "items/tools", "pickaxe_": "items/tools", "watering_can": "items/tools", "wheat_seed": "items/seeds", "potato_seed": "items/seeds", "corn_seed": "items/seeds", # UI "ui_": "ui", } def classify_asset(filename: str) -> str: """Determine where an asset should go based on its name.""" for pattern, target in RULES.items(): if pattern in filename.lower(): return target # Default: keep in current subfolder structure return None def scan_demo_folder(): """Scan demo folder and classify all assets.""" migrations = defaultdict(list) for filepath in DEMO_DIR.rglob("*.png"): # Skip if it's in a nested preview/original folder if "preview" in filepath.parts or "original" in filepath.parts: continue relative_to_demo = filepath.relative_to(DEMO_DIR) target_category = classify_asset(filepath.name) if target_category: migrations[target_category].append(filepath) else: # Keep the subfolder structure (characters/, buildings/, etc.) subfolder = relative_to_demo.parts[0] if len(relative_to_demo.parts) > 1 else "misc" migrations[subfolder].append(filepath) return migrations def create_target_directories(): """Ensure all target directories exist.""" for target_path in TARGETS.values(): target_path.mkdir(parents=True, exist_ok=True) # Additional specific directories (ASSETS_DIR / "effects/particles").mkdir(parents=True, exist_ok=True) def migrate_assets(migrations, dry_run=False): """Move assets to their target locations.""" stats = defaultdict(int) for category, files in migrations.items(): target_dir = TARGETS.get(category) if not target_dir: # Use direct category as subdirectory target_dir = ASSETS_DIR / category target_dir.mkdir(parents=True, exist_ok=True) print(f"\nšŸ“ {category}/ ({len(files)} files)") for src_file in files: dest_file = target_dir / src_file.name if dry_run: print(f" [DRY RUN] {src_file.name} → {target_dir.name}/") else: try: shutil.move(str(src_file), str(dest_file)) print(f" āœ… {src_file.name}") stats[category] += 1 except Exception as e: print(f" āŒ {src_file.name}: {e}") return stats def main(): dry_run = "--dry-run" in sys.argv print("═" * 70) print("šŸ”„ DEMO → PRODUCTION ASSET MIGRATION") print("═" * 70) if dry_run: print("āš ļø DRY RUN MODE - No files will be moved\n") # Step 1: Scan print("šŸ“Š Scanning demo folder...") migrations = scan_demo_folder() # Step 2: Create directories print("\nšŸ“ Creating target directories...") create_target_directories() # Step 3: Migrate print("\n🚚 Migrating assets...") stats = migrate_assets(migrations, dry_run=dry_run) # Summary print("\n" + "═" * 70) print("šŸ“Š MIGRATION SUMMARY") print("═" * 70) total = sum(stats.values()) for category, count in sorted(stats.items()): print(f" {category:40s} {count:3d} files") print("─" * 70) print(f" {'TOTAL':40s} {total:3d} files") print("═" * 70) if dry_run: print("\nšŸ’” Run without --dry-run to perform the migration") else: print("\nāœ… Migration complete!") print("\nšŸ“ Next steps:") print(" 1. Review the changes: git status") print(" 2. Test the game to ensure assets load correctly") print(" 3. Commit the reorganization: git add -A && git commit -m 'šŸ—‚ļø Migrate demo assets to production structure'") if __name__ == "__main__": main()