Files
novafarma/scripts/autonomous_generation.py

254 lines
11 KiB
Python
Executable File

#!/usr/bin/env python3
"""
AUTONOMOUS OVERNIGHT GENERATION SCRIPT
Directly calls Google Vertex AI Imagen API without needing Antigravity
SETUP:
1. pip3 install google-cloud-aiplatform Pillow
2. Set GOOGLE_APPLICATION_CREDENTIALS environment variable
3. python3 scripts/autonomous_generation.py
USAGE:
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
python3 scripts/autonomous_generation.py --batch 422
"""
import os
import sys
import time
import json
import argparse
from datetime import datetime
from pathlib import Path
import subprocess
try:
from google.cloud import aiplatform
from vertexai.preview.vision_models import ImageGenerationModel
except ImportError:
print("ERROR: Missing dependencies!")
print("Install: pip3 install google-cloud-aiplatform Pillow")
sys.exit(1)
# GRITTY NOIR STYLE TEMPLATE
STYLE_SUFFIX = ", game asset, (bold black outlines:1.4), dark hand-drawn stylized indie game asset, (gritty noir aesthetic:1.2), flat colors, muted color palette, isolated object centered on solid white background, clean edges, simple composition"
# NEGATIVE PROMPT
NEGATIVE_PROMPT = "pixel art, pixels, grainy, blurry, 3D rendering, realistic photo, shading gradients, Disney style, cute kawaii, bright colors, complex background, environment elements, shadows on ground, textured background"
# PRODUCTION QUEUE - All 422 base assets
ASSET_QUEUE = {
"buildings": [
("tent", "small camping tent, triangular canvas tent"),
("shack", "wooden shack, rustic wooden hut"),
("farmhouse_basic", "basic farmhouse building, small two-story house with chimney"),
("farmhouse_complete", "complete farmhouse, large two-story house with chimney"),
("barn", "barn building, large red barn for animals"),
("greenhouse", "greenhouse building, glass structure for plants"),
("workshop", "workshop building, craftsman shed with tools"),
("laboratory", "laboratory building, science research facility"),
("vape_lab", "vape lab building, chemistry workshop for liquids"),
("bakery", "bakery building, cozy bakery shop with oven"),
("blacksmith_shop", "blacksmith shop, stone forge with anvil sign"),
("clinic", "clinic building, medical facility with red cross"),
("church_ruined", "ruined church, destroyed stone church building"),
("church_complete", "complete church, intact stone church with steeple"),
("tavern", "tavern building, cozy inn with hanging sign"),
("town_hall", "town hall, administrative building with clock tower"),
("warehouse", "warehouse building, large storage facility"),
("inn", "inn building, travelers rest stop"),
("windmill", "windmill, tall wooden windmill with blades"),
("watchtower", "watchtower, tall stone tower with platform"),
# Add more buildings as needed...
],
"crops": [
("wheat_seed", "wheat seeds planted in soil, brown seeds in dirt, planting stage, farm crop sprite"),
("wheat_growing", "wheat plant growing, young green sprouts, farm crop sprite"),
("wheat_harvest", "wheat ready to harvest, golden stalks, farm crop sprite"),
("corn_seed", "corn seeds in soil, planting stage, farm crop sprite"),
("corn_growing", "corn plant growing, tall green stalk, farm crop sprite"),
("corn_harvest", "corn ready to harvest, ripe yellow corn, farm crop sprite"),
("tomato_seed", "tomato seeds in soil, planting stage, farm crop sprite"),
("tomato_growing", "tomato plant growing, green bush, farm crop sprite"),
("tomato_harvest", "tomato plant with red tomatoes, farm crop sprite"),
("potato_growing", "potato plant growing, leafy green plant, farm crop sprite"),
("carrot_growing", "carrot plant with orange top visible, farm crop sprite"),
("pumpkin_growing", "pumpkin plant with orange pumpkin, farm crop sprite"),
("hemp_growing", "hemp plant growing, tall cannabis plant, farm crop sprite"),
# Add more crops...
],
"npcs": [
("npc_trader", "trader NPC, merchant with backpack and hat, game NPC sprite"),
("npc_blacksmith", "blacksmith NPC, muscular man with apron and hammer, game NPC sprite"),
("npc_baker", "baker NPC, friendly woman with chef hat, game NPC sprite"),
("npc_farmer", "farmer NPC, elderly man with straw hat and pitchfork, game NPC sprite"),
("npc_guard", "guard NPC, armored guard with spear, game NPC sprite"),
("npc_healer", "healer NPC, medic with medical bag, game NPC sprite"),
("npc_hunter", "hunter NPC, forest hunter with bow, game NPC sprite"),
("npc_mechanic", "mechanic NPC, engineer with wrench, game NPC sprite"),
# Add more NPCs...
],
"animals": [
("cow", "cow farm animal, brown and white dairy cow, game creature sprite"),
("chicken", "chicken farm animal, white hen with red comb, game creature sprite"),
("pig", "pig farm animal, pink pig with curly tail, game creature sprite"),
("horse", "horse farm animal, brown horse with saddle, game creature sprite"),
("sheep", "sheep farm animal, fluffy white sheep, game creature sprite"),
("mutant_cow", "mutant cow with extra udders, game creature sprite"),
("fire_sheep", "fire sheep with flaming orange wool, game creature sprite"),
("three_headed_chicken", "three-headed chicken mutant, game creature sprite"),
("undead_horse", "undead horse with skeleton features, game creature sprite"),
# Add more animals...
],
}
class AutonomousGenerator:
def __init__(self, project_id: str, location: str = "us-central1"):
"""Initialize the autonomous generator"""
self.project_id = project_id
self.location = location
self.log_file = Path("generation_log.txt")
self.errors_file = Path("generation_errors.txt")
# Initialize Vertex AI
aiplatform.init(project=project_id, location=location)
self.model = ImageGenerationModel.from_pretrained("imagegeneration@006")
print(f"✅ Initialized Vertex AI: {project_id} ({location})")
def generate_image(self, asset_name: str, prompt: str, category: str) -> bool:
"""Generate a single image using Vertex AI Imagen"""
try:
full_prompt = prompt + STYLE_SUFFIX
# Generate image
response = self.model.generate_images(
prompt=full_prompt,
negative_prompt=NEGATIVE_PROMPT,
number_of_images=1,
aspect_ratio="1:1",
safety_filter_level="block_some",
)
if not response.images:
raise Exception("No images returned from API")
# Save image
output_dir = Path(f"assets/images/{category}")
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / f"{asset_name}.png"
response.images[0].save(str(output_path))
self.log(f"✅ Generated: {asset_name}{output_path}")
return True
except Exception as e:
error_msg = f"❌ FAILED: {asset_name} - {str(e)}"
self.log(error_msg, error=True)
return False
def log(self, message: str, error: bool = False):
"""Log message to file and console"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_msg = f"[{timestamp}] {message}"
print(log_msg)
log_file = self.errors_file if error else self.log_file
with open(log_file, "a") as f:
f.write(log_msg + "\n")
def git_commit(self, count: int):
"""Create git commit"""
try:
subprocess.run(["git", "add", "assets/images/"], check=True)
subprocess.run([
"git", "commit", "-m",
f"feat: Auto-generated {count} assets via autonomous script"
], check=True)
self.log(f"📝 Git commit created ({count} assets)")
except Exception as e:
self.log(f"⚠️ Git commit failed: {e}", error=True)
def run(self, max_assets: int = None):
"""Run the autonomous generation"""
self.log("🚀 STARTING AUTONOMOUS GENERATION")
self.log(f"Target: {max_assets or 'ALL'} assets")
total_generated = 0
total_failed = 0
commit_batch = []
for category, assets in ASSET_QUEUE.items():
self.log(f"\n📁 Category: {category}")
for asset_name, prompt in assets:
if max_assets and total_generated >= max_assets:
self.log(f"\n✅ Reached target: {max_assets} assets")
break
# Generate image
success = self.generate_image(asset_name, prompt, category)
if success:
total_generated += 1
commit_batch.append(asset_name)
# Git commit every 20 assets
if len(commit_batch) >= 20:
self.git_commit(len(commit_batch))
commit_batch = []
else:
total_failed += 1
# Wait 60 seconds between requests (API rate limit)
if total_generated % 10 == 0:
self.log(f"📊 Progress: {total_generated} generated, {total_failed} failed")
time.sleep(60) # API cooldown
# Final commit
if commit_batch:
self.git_commit(len(commit_batch))
# Summary
self.log("\n" + "="*70)
self.log("🎉 GENERATION COMPLETE!")
self.log(f"✅ Successfully generated: {total_generated}")
self.log(f"❌ Failed: {total_failed}")
self.log("="*70)
def main():
parser = argparse.ArgumentParser(description="Autonomous asset generation")
parser.add_argument("--project", default=os.getenv("GOOGLE_CLOUD_PROJECT"),
help="Google Cloud Project ID")
parser.add_argument("--batch", type=int, help="Max assets to generate")
args = parser.parse_args()
if not args.project:
print("ERROR: No project ID specified!")
print("Set GOOGLE_CLOUD_PROJECT env var or use --project flag")
sys.exit(1)
# Check credentials
if not os.getenv("GOOGLE_APPLICATION_CREDENTIALS"):
print("WARNING: GOOGLE_APPLICATION_CREDENTIALS not set!")
print("Set it to your service account JSON file path")
# Run generation
generator = AutonomousGenerator(args.project)
generator.run(max_assets=args.batch)
if __name__ == "__main__":
main()