🔧 Fixed generation scripts - proper image saving, gemini-1.5-flash model, full logging

This commit is contained in:
2025-12-31 10:17:19 +01:00
parent 56bd968c6d
commit fddc9021bb
2 changed files with 108 additions and 46 deletions

View File

@@ -2,7 +2,6 @@
""" """
🦖 ANOMALOUS ZONE FAUNA GENERATOR 🦖 ANOMALOUS ZONE FAUNA GENERATOR
Generates creatures for all 8 remaining anomalous zones Generates creatures for all 8 remaining anomalous zones
Based on DLC_TO_BASE_GAME_COMPLETE.md specifications Based on DLC_TO_BASE_GAME_COMPLETE.md specifications
""" """
@@ -10,6 +9,7 @@ import os
import sys import sys
import time import time
from pathlib import Path from pathlib import Path
from PIL import Image
try: try:
import google.generativeai as genai import google.generativeai as genai
@@ -30,16 +30,13 @@ if not api_key:
sys.exit(1) sys.exit(1)
genai.configure(api_key=api_key) genai.configure(api_key=api_key)
model = genai.GenerativeModel("gemini-2.0-flash-exp")
# Style prompts # Style prompts
STYLE_A = """2D indie game creature sprite, cartoon vector art style, bold black outlines, STYLE_A = """ISOLATED ON PURE WHITE BACKGROUND. 2D indie game creature sprite, cartoon vector art style, bold black outlines,
flat colors, cute and playful aesthetic, NO shadows, NO gradients, simple clean design, flat colors, cute and playful aesthetic, NO shadows, NO gradients, simple clean design, centered, full body visible, game asset"""
centered on white background, full body visible, game asset"""
STYLE_B = """2D indie game creature sprite, dark hand-drawn gritty noir style, STYLE_B = """ISOLATED ON PURE WHITE BACKGROUND. 2D indie game creature sprite, dark hand-drawn gritty noir style,
dramatic shadows, high contrast, sketchy atmospheric lines, mature 90s cartoon aesthetic, dramatic shadows, high contrast, sketchy atmospheric lines, mature 90s cartoon aesthetic, centered, full body visible, game asset"""
centered on white background, full body visible, game asset"""
# All anomalous zones with their creatures # All anomalous zones with their creatures
ANOMALOUS_ZONES = { ANOMALOUS_ZONES = {
@@ -116,81 +113,146 @@ ANOMALOUS_ZONES = {
], ],
} }
def generate_creature(zone_name: str, creature_name: str, description: str, style: str) -> bool: def create_preview(image_path: Path, size=256):
"""Create preview version"""
try:
img = Image.open(image_path)
preview = img.resize((size, size), Image.Resampling.LANCZOS)
preview_path = image_path.parent / f"{image_path.stem}_preview_{size}x{size}.png"
preview.save(preview_path, 'PNG', optimize=True)
return preview_path
except Exception as e:
print(f" ⚠️ Preview failed: {e}")
return None
def generate_creature(zone_name: str, creature_name: str, description: str, style: str, log_file) -> bool:
"""Generate a single creature sprite""" """Generate a single creature sprite"""
start = time.time()
style_suffix = "stylea" if style == "A" else "styleb" style_suffix = "stylea" if style == "A" else "styleb"
output_path = ASSETS / zone_name / f"{creature_name}_{style_suffix}.png" output_path = ASSETS / zone_name / f"{creature_name}_{style_suffix}.png"
# Skip if exists # Skip if exists
if output_path.exists(): if output_path.exists():
print(f" ⏭️ Already exists")
return True return True
# Create prompt # Create prompt
style_prompt = STYLE_A if style == "A" else STYLE_B style_prompt = STYLE_A if style == "A" else STYLE_B
full_prompt = f"{style_prompt}, {description}" full_prompt = f"{style_prompt}\n\n{description}\n\nGame sprite asset."
try: try:
print(f" 🎨 Generating {style_suffix}: {creature_name}")
log_file.write(f"{time.strftime('%H:%M:%S')} - Generating {output_path.name}\n")
log_file.flush()
# Generate image # Generate image
result = model.generate_content([full_prompt]) model = genai.GenerativeModel("gemini-1.5-flash")
response = model.generate_content([full_prompt])
# Save (this is placeholder - actual implementation needs image saving) if hasattr(response, '_result') and response._result.candidates:
output_path.parent.mkdir(parents=True, exist_ok=True) image_data = response._result.candidates[0].content.parts[0].inline_data.data
# Note: Actual saving logic would go here # Save original
# For now, this is a template output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'wb') as f:
return True f.write(image_data)
# Create preview
preview = create_preview(output_path)
elapsed = time.time() - start
print(f" ✅ Saved ({elapsed:.1f}s)")
log_file.write(f"{time.strftime('%H:%M:%S')} - SUCCESS {output_path.name} ({elapsed:.1f}s)\n")
log_file.flush()
return True
else:
print(f" ❌ No image data")
log_file.write(f"{time.strftime('%H:%M:%S')} - FAILED {output_path.name} - No data\n")
log_file.flush()
return False
except Exception as e: except Exception as e:
print(f" ❌ Error: {e}") print(f" ❌ Error: {e}")
log_file.write(f"{time.strftime('%H:%M:%S')} - ERROR {output_path.name} - {e}\n")
log_file.flush()
return False return False
def main(): def main():
# Create log
log_dir = REPO / "logs"
log_dir.mkdir(exist_ok=True)
log_file = open(log_dir / f"anomalous_fauna_{time.strftime('%Y%m%d_%H%M%S')}.log", 'w')
print("="*70) print("="*70)
print("🦖 ANOMALOUS ZONE FAUNA GENERATOR") print("🦖 ANOMALOUS ZONE FAUNA GENERATOR")
print("="*70) print("="*70)
print(f"\nGenerating creatures for {len(ANOMALOUS_ZONES)} zones...")
total_creatures = sum(len(creatures) for creatures in ANOMALOUS_ZONES.values()) total_creatures = sum(len(creatures) for creatures in ANOMALOUS_ZONES.values())
total_images = total_creatures * 2 # styleA + styleB total_images = total_creatures * 2 # styleA + styleB
print(f"Total: {total_creatures} creatures × 2 styles = {total_images} images") print(f"\n{len(ANOMALOUS_ZONES)} zones | {total_creatures} creatures × 2 styles = {total_images} images")
print() print()
log_file.write(f"ANOMALOUS FAUNA GENERATION - {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
log_file.write(f"Total: {total_images} images\n")
log_file.write("="*70 + "\n\n")
log_file.flush()
success = 0 success = 0
failed = 0 failed = 0
current = 0 current = 0
for zone_name, creatures in ANOMALOUS_ZONES.items(): try:
print(f"\n🌍 {zone_name.upper().replace('_', ' ')}") for zone_name, creatures in ANOMALOUS_ZONES.items():
print(f" {len(creatures)} creatures") print(f"\n{'='*70}")
print(f"🌍 {zone_name.upper().replace('_', ' ')}")
for creature_name, description in creatures: print(f"{'='*70}")
current += 1 print(f" {len(creatures)} creatures")
print(f"\n[{current}/{total_creatures}] {creature_name}")
# Generate both styles log_file.write(f"\n{'='*70}\n")
for style in ["A", "B"]: log_file.write(f"ZONE: {zone_name}\n")
style_name = "Cartoon" if style == "A" else "Noir" log_file.write(f"{'='*70}\n\n")
print(f" 🎨 Style {style} ({style_name})...", end=" ") log_file.flush()
for creature_name, description in creatures:
current += 1
print(f"\n[{current}/{total_creatures}] {creature_name}")
if generate_creature(zone_name, creature_name, description, style): # Generate both styles
print("") for style in ["A", "B"]:
success += 1 if generate_creature(zone_name, creature_name, description, style, log_file):
else: success += 1
print("") else:
failed += 1 failed += 1
# Rate limiting
time.sleep(2)
# Rate limiting # Progress
time.sleep(2) progress = ((current / total_creatures) * 100)
print(f"\n📊 Progress: {progress:.1f}% | Success: {success}/{total_images} | Failed: {failed}")
# Final summary
print("\n" + "="*70)
print("🎉 GENERATION COMPLETE!")
print("="*70)
print(f"✅ Success: {success}/{total_images}")
print(f"❌ Failed: {failed}/{total_images}")
print(f"📊 Success rate: {(success/total_images)*100:.1f}%")
log_file.write(f"\n{'='*70}\n")
log_file.write(f"GENERATION COMPLETE\n")
log_file.write(f"Success: {success}\n")
log_file.write(f"Failed: {failed}\n")
except KeyboardInterrupt:
print(f"\n\n⚠️ INTERRUPTED at creature {current}")
log_file.write(f"\n\nINTERRUPTED at creature {current}\n")
print("\n" + "="*70) finally:
print("🎉 GENERATION COMPLETE!") log_file.close()
print("="*70)
print(f"✅ Success: {success}/{total_images}")
print(f"❌ Failed: {failed}/{total_images}")
print(f"📊 Success rate: {(success/total_images)*100:.1f}%")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -43,7 +43,7 @@ def generate_image(prompt: str, output_path: Path, log_file):
log_file.write(f"{time.strftime('%H:%M:%S')} - Generating {output_path.name}\n") log_file.write(f"{time.strftime('%H:%M:%S')} - Generating {output_path.name}\n")
log_file.flush() log_file.flush()
model = genai.GenerativeModel('gemini-2.0-flash-exp') model = genai.GenerativeModel('gemini-1.5-flash')
response = model.generate_content([prompt]) response = model.generate_content([prompt])
if hasattr(response, '_result') and response._result.candidates: if hasattr(response, '_result') and response._result.candidates: