This commit is contained in:
2025-12-30 23:48:51 +01:00
parent a072fd48b1
commit 190d45edfa
399 changed files with 3914 additions and 1 deletions

200
scripts/create_full_structure.sh Executable file
View File

@@ -0,0 +1,200 @@
#!/bin/bash
# Complete folder structure creator for DolinaSmrti
# Creates ~150+ organized folders for all game assets
cd /Users/davidkotnik/repos/novafarma/assets/images
echo "🗂️ Creating complete asset structure..."
# ========================================
# BIOMES (18 total)
# ========================================
# 01. Dolina Farm (Starting)
mkdir -p biomes/01_dolina_farm/{terrain,buildings,props,crops,npcs,enemies}
# 02. Dark Forest
mkdir -p biomes/02_dark_forest/{terrain,trees,buildings,props,npcs,enemies}
# 03. Abandoned Town
mkdir -p biomes/03_abandoned_town/{terrain,buildings,streets,props,npcs,enemies}
# 04. River Valley
mkdir -p biomes/04_river_valley/{terrain,water,buildings,props,npcs,enemies}
# 05. Mountain Pass
mkdir -p biomes/05_mountain_pass/{terrain,rocks,buildings,props,npcs,enemies}
# 06. Swamp
mkdir -p biomes/06_swamp/{terrain,water,buildings,props,plants,npcs,enemies}
# 07. Desert
mkdir -p biomes/07_desert/{terrain,buildings,props,npcs,enemies}
# 08. Snow Zone
mkdir -p biomes/08_snow_zone/{terrain,ice,buildings,props,npcs,enemies}
# 09. Underground
mkdir -p biomes/09_underground/{terrain,crystals,buildings,props,npcs,enemies}
# 10. Magical Grove
mkdir -p biomes/10_magical_grove/{terrain,magical_trees,buildings,props,plants,npcs,enemies}
# 11. Ancient Ruins
mkdir -p biomes/11_ancient_ruins/{terrain,structures,buildings,props,npcs,enemies}
# 12. Coastal Area
mkdir -p biomes/12_coastal_area/{terrain,water,buildings,props,npcs,enemies}
# 13. Volcano
mkdir -p biomes/13_volcano/{terrain,lava,buildings,props,npcs,enemies}
# 14. Crystal Caves
mkdir -p biomes/14_crystal_caves/{terrain,crystals,buildings,props,npcs,enemies}
# 15. Floating Islands
mkdir -p biomes/15_floating_islands/{terrain,sky,buildings,props,npcs,enemies}
# 16. Corrupted Lands
mkdir -p biomes/16_corrupted_lands/{terrain,corruption,buildings,props,npcs,enemies}
# 17. Spirit Realm
mkdir -p biomes/17_spirit_realm/{terrain,ethereal,buildings,props,npcs,enemies}
# 18. Final Zone
mkdir -p biomes/18_final_zone/{terrain,epic,buildings,props,npcs,enemies}
# ========================================
# CHARACTERS (Main)
# ========================================
mkdir -p characters/kai/{idle,walk,run,actions,combat,portraits,emotions}
mkdir -p characters/gronk/{idle,walk,run,actions,combat,portraits,emotions}
mkdir -p characters/grok/{idle,walk,run,actions,combat,portraits,emotions}
mkdir -p characters/ana/{idle,walk,run,actions,portraits,emotions,cutscenes}
mkdir -p characters/susi_dog/{idle,walk,run,actions}
# ========================================
# NPCS (Generic categories)
# ========================================
mkdir -p npcs/farmers/{idle,walk,work,portraits}
mkdir -p npcs/merchants/{idle,walk,work,portraits}
mkdir -p npcs/guards/{idle,walk,patrol,portraits}
mkdir -p npcs/civilians/{idle,walk,work,portraits}
mkdir -p npcs/special_characters/{idle,walk,unique,portraits}
mkdir -p npcs/children/{idle,walk,play,portraits}
mkdir -p npcs/elderly/{idle,walk,sit,portraits}
# ========================================
# ENEMIES (All types)
# ========================================
mkdir -p enemies/zombies/{common,soldier,mutant,boss}
mkdir -p enemies/animals/{wolves,bears,deer,birds}
mkdir -p enemies/mutants/{small,medium,large,boss}
mkdir -p enemies/magical_creatures/{sprites,elementals,wraiths,boss}
mkdir -p enemies/corrupted/{plants,animals,humanoids,boss}
mkdir -p enemies/bosses/{forest,town,mountain,desert,final}
# ========================================
# ITEMS (All categories)
# ========================================
# Tools
mkdir -p items/tools/{farming,combat,magic,fishing,mining}
# Seeds
mkdir -p items/seeds/{crops,flowers,trees,magical}
# Food
mkdir -p items/food/{raw,cooked,baked,preserved,special}
# Resources
mkdir -p items/resources/{wood,stone,ore,gems,magical}
# Equipment
mkdir -p items/equipment/{weapons,armor,accessories,special}
# Magical
mkdir -p items/magical/{spells,scrolls,potions,artifacts,crystals}
# Crafting
mkdir -p items/crafting/{materials,components,reagents}
# ========================================
# UI (Interface elements)
# ========================================
# HUD
mkdir -p ui/hud/{health,stamina,mana,buffs,debuffs}
# Menus
mkdir -p ui/menus/{main,inventory,crafting,skills,quests,map,settings}
# Dialogue
mkdir -p ui/dialogue/{boxes,portraits,buttons,backgrounds}
# Icons
mkdir -p ui/icons/{items,skills,status,achievements,quest_markers}
# Panels
mkdir -p ui/panels/{stats,equipment,social,achievements}
# Buttons
mkdir -p ui/buttons/{normal,hover,pressed,disabled}
# ========================================
# EFFECTS (Visual effects)
# ========================================
# Magic
mkdir -p effects/magic/{fire,water,earth,air,dark,light,combo}
# Weather
mkdir -p effects/weather/{rain,snow,fog,storm,wind}
# Particles
mkdir -p effects/particles/{sparkles,smoke,dust,blood,energy}
# Animations
mkdir -p effects/animations/{explosions,impacts,transitions,auras,shields}
# Environmental
mkdir -p effects/environmental/{day_night,seasons,lighting}
# ========================================
# BUILDINGS (For all biomes)
# ========================================
mkdir -p buildings/residential/{houses,apartments,mansions}
mkdir -p buildings/commercial/{shops,markets,taverns}
mkdir -p buildings/industrial/{barns,mills,workshops}
mkdir -p buildings/special/{churches,schools,hospitals}
mkdir -p buildings/ruins/{damaged,destroyed,ancient}
# ========================================
# PROPS (Environmental objects)
# ========================================
mkdir -p props/natural/{rocks,trees,plants,water_features}
mkdir -p props/furniture/{indoor,outdoor}
mkdir -p props/decorative/{statues,signs,paintings}
mkdir -p props/interactive/{doors,chests,switches,levers}
# ========================================
# CUTSCENES
# ========================================
mkdir -p cutscenes/opening/{frames,backgrounds}
mkdir -p cutscenes/story/{act1,act2,act3}
mkdir -p cutscenes/ending/{frames,backgrounds}
echo ""
echo "✅ COMPLETE! Structure created:"
echo ""
find . -type d -maxdepth 1 | wc -l | xargs echo " Main categories:"
find . -type d -maxdepth 2 | wc -l | xargs echo " Subcategories:"
find . -type d -maxdepth 3 | wc -l | xargs echo " Total folders:"
echo ""
echo "🎨 READY FOR MASS GENERATION!"

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,146 @@
#!/usr/bin/env python3
"""
Reorganize assets with proper structure:
- Each asset gets its own subfolder
- Original 1024x1024 file: assetname_1024x1024.png
- Resized file: assetname_32x32.png (or other size)
"""
import os
import shutil
from pathlib import Path
from PIL import Image
# Target sizes for each category
RESIZE_CONFIG = {
'terrain': 32,
'crops': 32,
'buildings': 32,
'items': 16,
'ui': None, # Keep original
'effects': 32,
'environment': {
'campfire': 32,
'dead_tree': (32, 64),
'rock': 32
},
'characters': 32,
'enemies': 32
}
def get_target_size(category: str, filename: str):
"""Get target resize dimensions"""
config = RESIZE_CONFIG.get(category)
if config is None:
return None
if isinstance(config, dict):
for key, size in config.items():
if key in filename:
return size
return 32
return config
def reorganize_asset(asset_path: Path, category_dir: Path, target_size):
"""
Reorganize single asset:
- Create subfolder with asset name
- Save original as assetname_1024x1024.png
- Save resized as assetname_32x32.png
"""
try:
# Get asset base name (without extension)
asset_name = asset_path.stem
# Create subfolder
asset_folder = category_dir / asset_name
asset_folder.mkdir(exist_ok=True)
# Load original
img = Image.open(asset_path)
orig_width, orig_height = img.size
# Save original with dimensions in name
original_filename = f"{asset_name}_{orig_width}x{orig_height}.png"
original_path = asset_folder / original_filename
img.save(original_path, 'PNG')
print(f" 📁 {asset_name}/")
print(f" ✅ Original: {original_filename} ({orig_width}×{orig_height})")
# Create resized version if needed
if target_size is not None:
if isinstance(target_size, tuple):
resized = img.resize(target_size, Image.Resampling.LANCZOS)
new_width, new_height = target_size
else:
resized = img.resize((target_size, target_size), Image.Resampling.LANCZOS)
new_width, new_height = target_size, target_size
resized_filename = f"{asset_name}_{new_width}x{new_height}.png"
resized_path = asset_folder / resized_filename
resized.save(resized_path, 'PNG', optimize=True)
print(f" ✅ Resized: {resized_filename} ({new_width}×{new_height})")
return True
except Exception as e:
print(f" ❌ Error with {asset_path.name}: {e}")
return False
def process_category(base_dir: Path, category: str):
"""Process all assets in category"""
category_path = base_dir / category
if not category_path.exists():
return 0
print(f"\n{'='*70}")
print(f"📂 CATEGORY: {category}/")
print(f"{'='*70}")
# Get all PNG files (not in subfolders)
png_files = [f for f in category_path.glob('*.png') if f.is_file()]
if not png_files:
print(" No PNG files found in root")
return 0
count = 0
for png_file in png_files:
target_size = get_target_size(category, png_file.stem)
if reorganize_asset(png_file, category_path, target_size):
# Remove original file after successful reorganization
png_file.unlink()
count += 1
return count
def main():
print("=" * 70)
print("🗂️ ASSET REORGANIZATION: SUBFOLDERS WITH ORIGINALS + RESIZED")
print("=" * 70)
demo_dir = Path('assets/images/demo')
print(f"\n📦 Processing: {demo_dir}")
total = 0
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += process_category(demo_dir, category)
total += process_category(demo_dir, 'environment')
print("\n" + "=" * 70)
print(f"✅ COMPLETE! Reorganized {total} assets")
print("=" * 70)
print("\n📁 Structure: category/assetname/")
print(" - assetname_1024x1024.png (original)")
print(" - assetname_32x32.png (resized)")
if __name__ == "__main__":
main()

129
scripts/resize_for_tiled.py Normal file
View File

@@ -0,0 +1,129 @@
#!/usr/bin/env python3
"""
Resize all demo assets to proper tile sizes for Tiled editor
Converts 1024x1024 generated images to game-appropriate sizes
"""
import os
from pathlib import Path
from PIL import Image
# Resize configurations
RESIZE_CONFIG = {
'terrain': 64, # 64x64 tiles
'crops': 64, # 64x64 tiles
'buildings': 64, # 64x64 (tent is square)
'items': 32, # 32x32 for inventory items
'ui': None, # Keep original size for UI
'effects': 48, # 48x48 for effects
'environment': { # Variable sizes
'campfire': 64,
'dead_tree': (64, 96), # Tall sprite
'rock': (48, 32) # Wide sprite
},
'characters': 64, # 64x64 for character sprites
'enemies': 64 # 64x64 for enemies
}
def resize_image(input_path: Path, output_path: Path, size):
"""Resize image maintaining aspect ratio or forcing size"""
try:
img = Image.open(input_path)
if size is None:
# Keep original
if input_path != output_path:
img.save(output_path, 'PNG')
return True
if isinstance(size, tuple):
# Force exact size (width, height)
resized = img.resize(size, Image.Resampling.LANCZOS)
else:
# Square resize
resized = img.resize((size, size), Image.Resampling.LANCZOS)
resized.save(output_path, 'PNG', optimize=True)
print(f"{output_path.name}: {img.size}{resized.size}")
return True
except Exception as e:
print(f" ❌ Error with {input_path.name}: {e}")
return False
def get_target_size(category: str, filename: str):
"""Determine target size based on category and filename"""
config = RESIZE_CONFIG.get(category)
if config is None:
return None
if isinstance(config, dict):
# Environment has variable sizes
for key, size in config.items():
if key in filename:
return size
return 64 # Default for environment
return config
def resize_category(base_dir: Path, category: str):
"""Resize all images in a category folder"""
category_path = base_dir / category
if not category_path.exists():
print(f"⚠️ Skipping {category} (not found)")
return 0
print(f"\n📁 Processing: {category}/")
png_files = list(category_path.glob('*.png'))
if not png_files:
print(f" No PNG files found")
return 0
count = 0
for png_file in png_files:
size = get_target_size(category, png_file.stem)
if resize_image(png_file, png_file, size):
count += 1
return count
def main():
print("=" * 60)
print("🖼️ RESIZING DEMO ASSETS FOR TILED")
print("=" * 60)
# Resize transparent assets
demo_dir = Path('assets/images/demo')
print(f"\n📦 TRANSPARENT ASSETS: {demo_dir}")
total = 0
for category in RESIZE_CONFIG.keys():
if category != 'environment': # Handle environment specially
total += resize_category(demo_dir, category)
# Environment with variable sizes
total += resize_category(demo_dir, 'environment')
# Resize white background originals
orig_dir = Path('assets/images/demo_originals_with_white_bg')
if orig_dir.exists():
print(f"\n📦 WHITE BG ORIGINALS: {orig_dir}")
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += resize_category(orig_dir, category)
total += resize_category(orig_dir, 'environment')
print("\n" + "=" * 60)
print(f"✅ COMPLETE! Resized {total} images")
print("=" * 60)
print("\n🗺️ Ready for Tiled! All assets now proper game sizes.")
if __name__ == "__main__":
main()

119
scripts/resize_to_32px.py Normal file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""
Resize to PROPER INDIE GAME sizes - 32x32 standard!
"""
import os
from pathlib import Path
from PIL import Image
# CORRECT sizes for indie games
RESIZE_CONFIG = {
'terrain': 32, # 32x32 tiles (Stardew Valley standard!)
'crops': 32, # 32x32 tiles
'buildings': 32, # 32x32
'items': 16, # 16x16 for inventory items (smaller!)
'ui': None, # Keep original
'effects': 24, # 24x24 for effects
'environment': { # Variable sizes
'campfire': 32,
'dead_tree': (32, 48), # Tall sprite
'rock': (24, 16) # Wide sprite
},
'characters': 32, # 32x32 for characters
'enemies': 32 # 32x32 for enemies
}
def resize_image(input_path: Path, output_path: Path, size):
"""Resize image maintaining quality"""
try:
img = Image.open(input_path)
if size is None:
if input_path != output_path:
img.save(output_path, 'PNG')
return True
if isinstance(size, tuple):
resized = img.resize(size, Image.Resampling.LANCZOS)
else:
resized = img.resize((size, size), Image.Resampling.LANCZOS)
resized.save(output_path, 'PNG', optimize=True)
print(f"{output_path.name}: {img.size}{resized.size}")
return True
except Exception as e:
print(f"{input_path.name}: {e}")
return False
def get_target_size(category: str, filename: str):
"""Determine target size"""
config = RESIZE_CONFIG.get(category)
if config is None:
return None
if isinstance(config, dict):
for key, size in config.items():
if key in filename:
return size
return 32 # Default
return config
def resize_category(base_dir: Path, category: str):
"""Resize all images in category"""
category_path = base_dir / category
if not category_path.exists():
return 0
print(f"\n📁 {category}/")
png_files = list(category_path.glob('*.png'))
if not png_files:
return 0
count = 0
for png_file in png_files:
size = get_target_size(category, png_file.stem)
if resize_image(png_file, png_file, size):
count += 1
return count
def main():
print("=" * 60)
print("🎮 RESIZING TO PROPER INDIE GAME SIZES (32×32 STANDARD)")
print("=" * 60)
demo_dir = Path('assets/images/demo')
print(f"\n📦 Transparent assets: {demo_dir}")
total = 0
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += resize_category(demo_dir, category)
total += resize_category(demo_dir, 'environment')
orig_dir = Path('assets/images/demo_originals_with_white_bg')
if orig_dir.exists():
print(f"\n📦 White BG originals: {orig_dir}")
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += resize_category(orig_dir, category)
total += resize_category(orig_dir, 'environment')
print("\n" + "=" * 60)
print(f"✅ DONE! Resized {total} images to 32×32 standard!")
print("=" * 60)
print("\n🎮 Perfect for indie games like Stardew Valley!")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,163 @@
#!/usr/bin/env python3
"""
Resize all assets to EXACT multiples of 32px tile size
Rename files to include dimensions: filename_WxH.png
"""
import os
from pathlib import Path
from PIL import Image
import shutil
# Exact tile-aligned sizes (multiples of 32)
TILE_SIZE = 32
RESIZE_CONFIG = {
'terrain': 32, # 1×1 tile
'crops': 32, # 1×1 tile
'buildings': 32, # 1×1 tile (tent)
'items': 16, # 0.5×0.5 tile (inventory items)
'ui': None, # Keep original
'effects': 32, # 1×1 tile (changed from 24)
'environment': {
'campfire': 32, # 1×1 tile
'dead_tree': (32, 64), # 1×2 tiles (changed from 32×48)
'rock': 32 # 1×1 tile (changed from 24×16)
},
'characters': 32, # 1×1 tile
'enemies': 32 # 1×1 tile
}
def resize_and_rename(input_path: Path, output_dir: Path, size, backup=True):
"""Resize image and rename with dimensions"""
try:
img = Image.open(input_path)
# Backup original if requested
if backup and input_path.parent == output_dir:
backup_path = input_path.parent / "originals" / input_path.name
backup_path.parent.mkdir(exist_ok=True)
if not backup_path.exists():
shutil.copy2(input_path, backup_path)
# Keep original if size is None
if size is None:
return True
# Resize
if isinstance(size, tuple):
resized = img.resize(size, Image.Resampling.LANCZOS)
new_width, new_height = size
else:
resized = img.resize((size, size), Image.Resampling.LANCZOS)
new_width, new_height = size, size
# Generate new filename with dimensions
stem = input_path.stem
# Remove old dimensions if present
if '_' in stem:
parts = stem.rsplit('_', 1)
if 'x' in parts[-1] or parts[-1].replace('x', '').replace('style', '').isdigit():
# Keep it as is for style suffixes
base_name = stem
else:
base_name = stem
else:
base_name = stem
# New filename: originalname_WxH.png
new_filename = f"{base_name}_{new_width}x{new_height}.png"
output_path = output_dir / new_filename
# Save
resized.save(output_path, 'PNG', optimize=True)
# Delete old file if different name
if output_path != input_path and input_path.exists():
input_path.unlink()
print(f"{input_path.name}{new_filename} ({img.size}{resized.size})")
return True
except Exception as e:
print(f"{input_path.name}: {e}")
return False
def get_target_size(category: str, filename: str):
"""Get target size for category"""
config = RESIZE_CONFIG.get(category)
if config is None:
return None
if isinstance(config, dict):
for key, size in config.items():
if key in filename:
return size
return 32 # Default
return config
def process_category(base_dir: Path, category: str):
"""Process all images in category"""
category_path = base_dir / category
if not category_path.exists():
return 0
print(f"\n📁 {category}/")
png_files = list(category_path.glob('*.png'))
if not png_files:
return 0
count = 0
for png_file in png_files:
# Skip already processed files with dimensions
if any(x in png_file.stem for x in ['_32x32', '_16x16', '_32x64', '_24x24']):
continue
size = get_target_size(category, png_file.stem)
if resize_and_rename(png_file, category_path, size):
count += 1
return count
def main():
print("=" * 70)
print("📏 TILE-ALIGNED RESIZE & RENAME (Multiples of 32px)")
print("=" * 70)
demo_dir = Path('assets/images/demo')
print(f"\n📦 Processing: {demo_dir}")
total = 0
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += process_category(demo_dir, category)
total += process_category(demo_dir, 'environment')
# White BG originals
orig_dir = Path('assets/images/demo_originals_with_white_bg')
if orig_dir.exists():
print(f"\n📦 Processing: {orig_dir}")
for category in RESIZE_CONFIG.keys():
if category != 'environment':
total += process_category(orig_dir, category)
total += process_category(orig_dir, 'environment')
print("\n" + "=" * 70)
print(f"✅ COMPLETE! Processed {total} images")
print("=" * 70)
print("\n📐 All sizes now multiples of 32px!")
print("📝 All files renamed with dimensions!")
print("\n🎮 Perfect for Tiled!")
if __name__ == "__main__":
main()