🔧 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
Generates creatures for all 8 remaining anomalous zones
Based on DLC_TO_BASE_GAME_COMPLETE.md specifications
"""
@@ -10,6 +9,7 @@ import os
import sys
import time
from pathlib import Path
from PIL import Image
try:
import google.generativeai as genai
@@ -30,16 +30,13 @@ if not api_key:
sys.exit(1)
genai.configure(api_key=api_key)
model = genai.GenerativeModel("gemini-2.0-flash-exp")
# Style prompts
STYLE_A = """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,
centered on white background, full body visible, game asset"""
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, centered, full body visible, game asset"""
STYLE_B = """2D indie game creature sprite, dark hand-drawn gritty noir style,
dramatic shadows, high contrast, sketchy atmospheric lines, mature 90s cartoon aesthetic,
centered on white background, full body visible, game asset"""
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, centered, full body visible, game asset"""
# All anomalous zones with their creatures
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"""
start = time.time()
style_suffix = "stylea" if style == "A" else "styleb"
output_path = ASSETS / zone_name / f"{creature_name}_{style_suffix}.png"
# Skip if exists
if output_path.exists():
print(f" ⏭️ Already exists")
return True
# Create prompt
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:
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
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)
output_path.parent.mkdir(parents=True, exist_ok=True)
# Note: Actual saving logic would go here
# For now, this is a template
return True
if hasattr(response, '_result') and response._result.candidates:
image_data = response._result.candidates[0].content.parts[0].inline_data.data
# Save original
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'wb') as f:
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:
print(f" ❌ Error: {e}")
log_file.write(f"{time.strftime('%H:%M:%S')} - ERROR {output_path.name} - {e}\n")
log_file.flush()
return False
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("🦖 ANOMALOUS ZONE FAUNA GENERATOR")
print("="*70)
print(f"\nGenerating creatures for {len(ANOMALOUS_ZONES)} zones...")
total_creatures = sum(len(creatures) for creatures in ANOMALOUS_ZONES.values())
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()
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
failed = 0
current = 0
for zone_name, creatures in ANOMALOUS_ZONES.items():
print(f"\n🌍 {zone_name.upper().replace('_', ' ')}")
print(f" {len(creatures)} creatures")
for creature_name, description in creatures:
current += 1
print(f"\n[{current}/{total_creatures}] {creature_name}")
try:
for zone_name, creatures in ANOMALOUS_ZONES.items():
print(f"\n{'='*70}")
print(f"🌍 {zone_name.upper().replace('_', ' ')}")
print(f"{'='*70}")
print(f" {len(creatures)} creatures")
# Generate both styles
for style in ["A", "B"]:
style_name = "Cartoon" if style == "A" else "Noir"
print(f" 🎨 Style {style} ({style_name})...", end=" ")
log_file.write(f"\n{'='*70}\n")
log_file.write(f"ZONE: {zone_name}\n")
log_file.write(f"{'='*70}\n\n")
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):
print("")
success += 1
else:
print("")
failed += 1
# Generate both styles
for style in ["A", "B"]:
if generate_creature(zone_name, creature_name, description, style, log_file):
success += 1
else:
failed += 1
# Rate limiting
time.sleep(2)
# Rate limiting
time.sleep(2)
# Progress
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)
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}%")
finally:
log_file.close()
if __name__ == "__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.flush()
model = genai.GenerativeModel('gemini-2.0-flash-exp')
model = genai.GenerativeModel('gemini-1.5-flash')
response = model.generate_content([prompt])
if hasattr(response, '_result') and response._result.candidates: