diff --git a/assets/images/npcs/kai_markovic.png b/assets/images/npcs/kai_markovic.png deleted file mode 100644 index 5b9aca061..000000000 Binary files a/assets/images/npcs/kai_markovic.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_idle1.png b/assets/images/npcs/kai_markovic_back_idle1.png deleted file mode 100644 index 27783df27..000000000 Binary files a/assets/images/npcs/kai_markovic_back_idle1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_idle2.png b/assets/images/npcs/kai_markovic_back_idle2.png deleted file mode 100644 index 01c81f838..000000000 Binary files a/assets/images/npcs/kai_markovic_back_idle2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_walk1.png b/assets/images/npcs/kai_markovic_back_walk1.png deleted file mode 100644 index 4b0ea5fd8..000000000 Binary files a/assets/images/npcs/kai_markovic_back_walk1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_walk2.png b/assets/images/npcs/kai_markovic_back_walk2.png deleted file mode 100644 index da21eafa8..000000000 Binary files a/assets/images/npcs/kai_markovic_back_walk2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_walk3.png b/assets/images/npcs/kai_markovic_back_walk3.png deleted file mode 100644 index 9928ea845..000000000 Binary files a/assets/images/npcs/kai_markovic_back_walk3.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_walk4.png b/assets/images/npcs/kai_markovic_back_walk4.png deleted file mode 100644 index dbc0c28e0..000000000 Binary files a/assets/images/npcs/kai_markovic_back_walk4.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_work1.png b/assets/images/npcs/kai_markovic_back_work1.png deleted file mode 100644 index 507ca080f..000000000 Binary files a/assets/images/npcs/kai_markovic_back_work1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_back_work2.png b/assets/images/npcs/kai_markovic_back_work2.png deleted file mode 100644 index 5240fc717..000000000 Binary files a/assets/images/npcs/kai_markovic_back_work2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_idle1.png b/assets/images/npcs/kai_markovic_front_idle1.png deleted file mode 100644 index 1931f7a18..000000000 Binary files a/assets/images/npcs/kai_markovic_front_idle1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_idle2.png b/assets/images/npcs/kai_markovic_front_idle2.png deleted file mode 100644 index 37baa7de8..000000000 Binary files a/assets/images/npcs/kai_markovic_front_idle2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_walk1.png b/assets/images/npcs/kai_markovic_front_walk1.png deleted file mode 100644 index 923963b13..000000000 Binary files a/assets/images/npcs/kai_markovic_front_walk1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_walk2.png b/assets/images/npcs/kai_markovic_front_walk2.png deleted file mode 100644 index e6628676c..000000000 Binary files a/assets/images/npcs/kai_markovic_front_walk2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_walk3.png b/assets/images/npcs/kai_markovic_front_walk3.png deleted file mode 100644 index 70edc70ea..000000000 Binary files a/assets/images/npcs/kai_markovic_front_walk3.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_walk4.png b/assets/images/npcs/kai_markovic_front_walk4.png deleted file mode 100644 index 105899d5d..000000000 Binary files a/assets/images/npcs/kai_markovic_front_walk4.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_work1.png b/assets/images/npcs/kai_markovic_front_work1.png deleted file mode 100644 index aafaff399..000000000 Binary files a/assets/images/npcs/kai_markovic_front_work1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_front_work2.png b/assets/images/npcs/kai_markovic_front_work2.png deleted file mode 100644 index 3392983b6..000000000 Binary files a/assets/images/npcs/kai_markovic_front_work2.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_left_idle1.png b/assets/images/npcs/kai_markovic_left_idle1.png deleted file mode 100644 index ee53769eb..000000000 Binary files a/assets/images/npcs/kai_markovic_left_idle1.png and /dev/null differ diff --git a/assets/images/npcs/kai_markovic_left_idle2.png b/assets/images/npcs/kai_markovic_left_idle2.png deleted file mode 100644 index 2858a1b7f..000000000 Binary files a/assets/images/npcs/kai_markovic_left_idle2.png and /dev/null differ diff --git a/scripts/generate_v63_stardew.py b/scripts/generate_v63_stardew.py new file mode 100644 index 000000000..aa5773b27 --- /dev/null +++ b/scripts/generate_v63_stardew.py @@ -0,0 +1,527 @@ +#!/usr/bin/env python3 +""" +🌾 DOLINA SMRTI V6.3 - STARDEW VALLEY INDI STYLE +¾ Top-down view, Hand-drawn 2.5D, Full Body Characters +Nomadic Post-Apocalyptic Slovenia Theme +""" + +import os +import json +import time +import uuid +import requests +from pathlib import Path +from typing import List, Dict + +# Configuration +COMFYUI_URL = "http://127.0.0.1:8000" +OUTPUT_DIR = "/Users/davidkotnik/repos/novafarma/assets/images" + +# ============================================================================ +# STARDEW VALLEY INDI STYLE - V6.3 +# ============================================================================ + +STYLE_PREFIX = """Stardew Valley game art style, ¾ three-quarter top-down perspective view, +2.5D hand-drawn indie game sprite, smooth clean lines, soft pastel colors with muted tones, +charming cartoon aesthetic, full body character visible from head to feet standing on ground, +legs clearly visible touching the floor not floating, +nomadic post-apocalyptic theme, worn clothing, survival gear, +isolated on transparent background with alpha channel, """ + +NEGATIVE_PROMPT = """pixel art, pixelated, voxel, 3d render, realistic photo, photorealistic, +anime face, manga style, chibi, floating, no legs, cut off legs, cropped body, +white background, solid background, blurry, low quality, watermark, text""" + +# ============================================================================ +# V6.3 MASTER REGISTRY - STARDEW INDI STYLE +# ============================================================================ + +def generate_v63_registry() -> List[Dict]: + """Generate complete V6.3 Stardew Indi Style asset registry""" + assets = [] + + # ======================================================================== + # 1. MAIN CHARACTERS - FULL BODY with All Animations + # ======================================================================== + + main_chars = [ + # GRONK - Nomadic Troll + ("gronk_troll", """Gronk massive nomadic troll character, wide strong build, + PINK dreadlocks hair, facial piercings, stretched earlobes with large gauges, + holding golden vape device smoking, peaceful wise expression, + tribal nomad clothing weathered, FULL BODY visible head to feet on ground, + Stardew Valley style sprite"""), + + # KAI - Protagonist + ("kai_survivor", """Kai nomadic survivor protagonist, athletic build, + GREEN natural dreadlocks hair, facial piercings nose and lip rings, + stretched earlobes with plugs, dirty worn blue jacket, + determined serious expression, survival backpack, + FULL BODY visible head to feet standing on ground, + Stardew Valley style sprite"""), + + # ANA - Twin Sister + ("ana_explorer", """Ana female explorer, Kai's twin sister, athletic, + natural dreadlocks, nomadic explorer outfit, magical bracelet on wrist, + kind determined expression, adventure gear, + FULL BODY visible head to feet on ground, + Stardew Valley style sprite"""), + ] + + # Add main characters with all animation frames + for name, prompt in main_chars: + # Base sprite + assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": prompt}) + + # 4-direction walk + idle + work animations (Stardew style) + for direction in ["front", "back", "left", "right"]: + for action in ["idle", "walk1", "walk2", "walk3", "walk4"]: + assets.append({ + "cat": "npcs", + "file": f"{name}_{direction}_{action}.png", + "prompt": f"{prompt}, {direction} facing view, {action} animation frame" + }) + # Work animations (chopping, mining) + for work in ["chop1", "chop2", "mine1", "mine2"]: + assets.append({ + "cat": "npcs", + "file": f"{name}_{direction}_{work}.png", + "prompt": f"{prompt}, {direction} facing, {work.replace('1','').replace('2','')} animation frame" + }) + + # ======================================================================== + # 2. NPCs - NOMADIC SURVIVORS + # ======================================================================== + + npcs = [ + ("npc_trader", "wasteland trader, nomadic merchant, cart of goods, weathered face, full body"), + ("npc_blacksmith", "nomadic blacksmith, leather apron, hammer, strong build, full body"), + ("npc_healer", "herbalist healer, herb pouch, kind elderly woman, full body"), + ("npc_hunter", "wasteland hunter, crossbow, animal pelts, rugged, full body"), + ("npc_farmer", "apocalypse farmer, patched overalls, hoe, weathered, full body"), + ("npc_mechanic", "mechanic survivor, oil stains, wrench, goggles, full body"), + ("npc_soldier", "ex-military survivor, tactical gear, rifle, alert, full body"), + ("npc_medic", "field medic, medical bag, bloodstained coat, tired, full body"), + ("npc_elder", "wise elder, walking stick, tribal markings, full body"), + ("npc_child", "survivor child, oversized clothes, hopeful, full body"), + ] + + for name, prompt in npcs: + assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": f"Stardew Valley style, {prompt}, standing on ground"}) + + # ======================================================================== + # 3. ŽIVALI (ANIMALS) - WITH ANIMATIONS + # ======================================================================== + + animals = [ + # Companions + ("susi_dachshund", "Susi dachshund dog, brown with spots, long body, floppy ears, loyal companion"), + ("dog_husky", "husky dog, fluffy, blue eyes, friendly"), + ("dog_shepherd", "german shepherd dog, protective, alert"), + ("cat_tabby", "tabby cat, orange stripes, curious"), + ("cat_black", "black cat, mysterious, green eyes"), + + # Farm Animals + ("cow_normal", "dairy cow, black and white holstein pattern, friendly"), + ("cow_brown", "brown cow, peaceful, grazing"), + ("sheep_white", "white sheep, fluffy wool, gentle"), + ("sheep_black", "black sheep, rare, dark wool"), + ("chicken_white", "white chicken, red comb, pecking"), + ("chicken_brown", "brown chicken, speckled feathers"), + ("rooster", "rooster, colorful tail, proud"), + ("pig_pink", "pink pig, curly tail, muddy"), + ("goat_white", "white goat, small horns, playful"), + ("horse_brown", "brown horse, riding, majestic"), + ("donkey", "grey donkey, large ears, sturdy"), + ("rabbit_brown", "brown rabbit, long ears, hopping"), + + # Legendary Animals + ("phoenix_chicken", "Phoenix Chicken, fire feathers, glowing orange-red, legendary"), + ("unicorn", "Unicorn, white horse, rainbow mane, golden spiral horn, magical"), + ("golden_goose", "Golden Goose, shimmering gold feathers, lays golden eggs"), + ("fire_sheep", "Fire Sheep, wool made of flames, glowing, magical mutant"), + ("three_headed_chicken", "Three-Headed Chicken, three heads, bizarre mutant"), + ("giant_pig", "Giant Pig, huge rideable size, saddle, strong"), + ("undead_horse", "Undead Horse, skeletal, ghostly mane, ethereal"), + ] + + for name, prompt in animals: + assets.append({ + "cat": "zivali", + "file": f"{name}.png", + "prompt": f"Stardew Valley style, {prompt}, full body side view, standing on ground" + }) + # Walk animation + for frame in ["walk1", "walk2", "idle"]: + assets.append({ + "cat": "zivali", + "file": f"{name}_{frame}.png", + "prompt": f"Stardew Valley style, {prompt}, {frame} animation frame" + }) + + # ======================================================================== + # 4. MUTANTI & ZOMBIES + # ======================================================================== + + mutants = [ + # Zombies + ("zombie_basic", "basic zombie, shambling, torn clothes, undead"), + ("zombie_runner", "fast zombie, sprinting, aggressive, rage"), + ("zombie_bloated", "bloated zombie, swollen, toxic, disgusting"), + ("zombie_armored", "armored zombie, riot gear, tough"), + ("zombie_crawler", "crawler zombie, no legs, crawling, grasping"), + + # Alpha Hybrids + ("alpha_wolf", "Alpha Wolf mutant, huge, glowing eyes, pack leader"), + ("alpha_bear", "Alpha Bear mutant, massive, irradiated, unstoppable"), + ("alpha_spider", "Alpha Spider mutant, giant, eight legs, web spinner"), + ("alpha_rat", "Alpha Rat mutant, dog-sized, diseased, swarm leader"), + + # Slimes + ("slime_green", "green slime, bouncing blob, basic"), + ("slime_blue", "blue slime, water element"), + ("slime_red", "red slime, fire element"), + ("slime_purple", "purple slime, poison element"), + ("slime_rainbow", "rainbow slime, all elements, rare"), + ] + + for name, prompt in mutants: + assets.append({ + "cat": "mutanti", + "file": f"{name}.png", + "prompt": f"Stardew Valley style, {prompt}, full body visible, standing/moving" + }) + # Attack and walk + for frame in ["walk1", "walk2", "attack1", "attack2"]: + assets.append({ + "cat": "mutanti", + "file": f"{name}_{frame}.png", + "prompt": f"Stardew Valley style, {prompt}, {frame} animation frame" + }) + + # ======================================================================== + # 5. 24 BOSSES - FULL BODY WITH ANIMATIONS + # ======================================================================== + + bosses = [ + ("boss_trex", "T-Rex dinosaur boss, massive prehistoric predator, huge jaws, tiny arms"), + ("boss_kraken", "Kraken boss, giant sea monster, tentacles, ocean terror"), + ("boss_alpha_troll_king", "Alpha Troll King boss, massive troll, crown, tribal armor, Gronk's enemy"), + ("boss_zombie_lord", "Zombie Lord boss, undead king, crown rotting, commands undead"), + ("boss_slime_king", "Slime King boss, giant slime with crown, bouncing"), + ("boss_dragon_fire", "Fire Dragon boss, red scales, breathing flames, flying"), + ("boss_dragon_ice", "Ice Dragon boss, blue scales, frost breath, majestic"), + ("boss_mutant_queen", "Mutant Queen boss, mother of mutants, egg sacs"), + ("boss_spider_empress", "Spider Empress boss, giant spider queen, web lair"), + ("boss_werewolf_alpha", "Werewolf Alpha boss, massive wolf-human, moonlight"), + ("boss_vampire_lord", "Vampire Lord boss, ancient vampire, cape, fangs"), + ("boss_lich_king", "Lich King boss, undead sorcerer, staff, magic"), + ("boss_golem_prime", "Golem Prime boss, massive stone construct, ancient"), + ("boss_phoenix", "Phoenix boss, giant fire bird, rebirth flames"), + ("boss_hydra", "Hydra boss, multi-headed serpent, regenerating"), + ("boss_chimera", "Chimera boss, lion goat serpent hybrid, savage"), + ("boss_cyclops", "Cyclops boss, one-eyed giant, club, powerful"), + ("boss_minotaur", "Minotaur boss, bull-headed warrior, labyrinth guardian"), + ("boss_giant_crab", "Giant Crab boss, massive claws, armored shell"), + ("boss_shadow_entity", "Shadow Entity boss, living darkness, consuming"), + ("boss_machine_titan", "Machine Titan boss, corrupted robot, military"), + ("boss_elder_treant", "Elder Treant boss, ancient living tree, nature"), + ("boss_demon_prince", "Demon Prince boss, hellfire, horns, terrifying"), + ("boss_leviathan", "Leviathan boss, world serpent, ocean depths"), + ] + + for name, prompt in bosses: + assets.append({ + "cat": "bosses", + "file": f"{name}.png", + "prompt": f"Stardew Valley style, {prompt}, FULL BODY visible from head to feet, 128px large sprite" + }) + # Boss animations + for frame in ["idle", "attack1", "attack2", "walk1", "walk2"]: + assets.append({ + "cat": "bosses", + "file": f"{name}_{frame}.png", + "prompt": f"Stardew Valley style, {prompt}, {frame} animation frame, full body visible" + }) + + # ======================================================================== + # 6. ENVIRONMENT - 18 BIOMES TILES (32x32 seamless) + # ======================================================================== + + biomes = { + "travnik": ["grass_green", "grass_flowers", "grass_dry"], + "gozd": ["forest_floor", "forest_moss", "forest_leaves"], + "mesto": ["concrete_cracked", "asphalt_broken", "rubble"], + "industrijska": ["metal_rusted", "factory_floor", "grate"], + "podzemlje": ["bunker_floor", "tunnel", "metro_tile"], + "katakombe": ["catacomb_stone", "catacomb_bones", "catacomb_moss"], + "mocvirje": ["swamp_mud", "swamp_water", "swamp_reeds"], + "pustinja": ["sand_hot", "sand_dunes", "cracked_earth"], + "sneg": ["snow_fresh", "snow_dirty", "ice"], + "gorovje": ["rock_grey", "rock_cliff", "gravel"], + "obala": ["beach_sand", "beach_wet", "pier_wood"], + "jezero": ["water_shallow", "water_deep", "lily_pads"], + "reka": ["river_flow", "riverbank", "river_rocks"], + "vulkan": ["lava_hot", "volcanic_rock", "ash_ground"], + "cernobil": ["radiation_zone", "contaminated", "dead_zone"], + "ruine": ["ruin_floor", "ruin_mosaic", "ruin_overgrown"], + "podvodni": ["ocean_floor", "coral", "seaweed"], + "atlantida": ["atlantis_marble", "atlantis_crystal", "atlantis_ruin"], + } + + for biome, tiles in biomes.items(): + for tile in tiles: + assets.append({ + "cat": "environment", + "file": f"tile_{biome}_{tile}.png", + "prompt": f"Stardew Valley style, {tile.replace('_', ' ')} ground tile, {biome} biome, 32x32 seamless tileable texture" + }) + + # Environment Objects + env_objects = [ + # Trees + ("tree_oak", "oak tree, green leaves, tall trunk"), + ("tree_pine", "pine tree, evergreen, cone shape"), + ("tree_dead", "dead tree, no leaves, gnarled branches"), + ("tree_palm", "palm tree, tropical, coconuts"), + ("tree_cherry", "cherry blossom tree, pink flowers"), + + # Ruins (Chernobyl) + ("ruin_reactor", "nuclear reactor ruins, Chernobyl style, radiation"), + ("ruin_apartment", "ruined apartment building, Soviet style"), + ("ruin_ferris_wheel", "abandoned ferris wheel, Pripyat style"), + ("ruin_hospital", "abandoned hospital, creepy, supplies"), + + # Atlantis + ("atlantis_pillar", "Atlantis marble pillar, underwater, ancient"), + ("atlantis_statue", "Atlantis goddess statue, barnacles, majestic"), + ("atlantis_temple", "Atlantis temple entrance, glowing crystals"), + + # Egypt + ("pyramid_large", "Egyptian pyramid, ancient, sandy"), + ("sphinx", "Sphinx statue, lion human, ancient mystery"), + ("obelisk", "Egyptian obelisk, hieroglyphs, tall"), + + # General Objects + ("rock_small", "small rocks, pebbles"), + ("rock_large", "large boulder, moss covered"), + ("bush_green", "green bush, leafy"), + ("bush_berry", "berry bush, fruits"), + ("flower_red", "red flowers, blooming"), + ("flower_blue", "blue flowers, blooming"), + ("mushroom_brown", "brown mushrooms, cluster"), + ("log_fallen", "fallen log, decomposing"), + ("campfire", "campfire, flames, warmth"), + ("tent_survivor", "survivor tent, makeshift camp"), + ] + + for name, prompt in env_objects: + assets.append({ + "cat": "environment", + "file": f"{name}.png", + "prompt": f"Stardew Valley style, {prompt}, game object sprite" + }) + + # ======================================================================== + # 7. ITEMS - WEAPONS, TOOLS, EQUIPMENT + # ======================================================================== + + items = [ + # Melee Weapons + ("weapon_axe_wood", "wooden axe, chopping tool"), + ("weapon_axe_iron", "iron axe, upgraded"), + ("weapon_axe_gold", "golden axe, magical"), + ("weapon_pickaxe_wood", "wooden pickaxe, mining"), + ("weapon_pickaxe_iron", "iron pickaxe, upgraded"), + ("weapon_sword_iron", "iron sword, combat"), + ("weapon_sword_silver", "silver sword, werewolf bane"), + ("weapon_hammer", "war hammer, crushing"), + ("weapon_spear", "wooden spear, hunting"), + + # Bows + ("weapon_bow_wood", "wooden bow, arrows"), + ("weapon_bow_silver", "silver bow, magical"), + ("weapon_crossbow", "crossbow, powerful"), + + # 6 Magic Wands + ("wand_fire", "fire magic wand, red crystal, flames"), + ("wand_ice", "ice magic wand, blue crystal, frost"), + ("wand_lightning", "lightning wand, yellow crystal, sparks"), + ("wand_earth", "earth magic wand, green crystal, nature"), + ("wand_shadow", "shadow magic wand, dark crystal, darkness"), + ("wand_healing", "healing magic wand, white crystal, restoration"), + + # Special Items + ("ana_bracelet", "Ana's magical bracelet, glowing, family heirloom"), + ("golden_vape", "Gronk's golden vape device, smoking"), + + # Equipment + ("backpack_small", "small backpack, leather"), + ("backpack_large", "large military backpack"), + ("gas_mask", "gas mask, protection"), + ("helmet_military", "military helmet"), + ("boots_combat", "combat boots"), + + # Resources + ("wood_logs", "wood logs, resource"), + ("stone_pile", "stone pile, resource"), + ("iron_ore", "iron ore, mining"), + ("gold_ore", "gold ore, valuable"), + ("crystal_blue", "blue crystal, magical"), + + # Consumables + ("potion_health", "health potion, red liquid"), + ("potion_mana", "mana potion, blue liquid"), + ("food_bread", "bread loaf, food"), + ("food_meat", "cooked meat, food"), + ("water_bottle", "water bottle, clean"), + ] + + for name, prompt in items: + assets.append({ + "cat": "items", + "file": f"{name}.png", + "prompt": f"Stardew Valley style, {prompt}, item sprite, inventory icon" + }) + + # ======================================================================== + # 8. UI ELEMENTS + # ======================================================================== + + ui = [ + ("ui_health_bar", "health bar, red hearts, Stardew style"), + ("ui_energy_bar", "energy bar, green lightning"), + ("ui_inventory_slot", "inventory slot, wooden frame"), + ("ui_button_menu", "menu button, wooden"), + ("ui_cursor_normal", "normal cursor, hand pointer"), + ("ui_cursor_interact", "interact cursor, grabbing hand"), + ] + + for name, prompt in ui: + assets.append({"cat": "ui", "file": f"{name}.png", "prompt": f"Stardew Valley style, {prompt}"}) + + return assets + + +# ============================================================================ +# COMFYUI INTEGRATION +# ============================================================================ + +def create_workflow(prompt_text: str, output_name: str) -> dict: + seed = int(time.time() * 1000) % 2147483647 + return { + "1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}}, + "2": {"class_type": "EmptyLatentImage", "inputs": {"width": 512, "height": 512, "batch_size": 1}}, + "3": {"class_type": "CLIPTextEncode", "inputs": {"text": STYLE_PREFIX + prompt_text, "clip": ["1", 1]}}, + "4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE_PROMPT, "clip": ["1", 1]}}, + "5": {"class_type": "KSampler", "inputs": { + "seed": seed, "steps": 30, "cfg": 7.5, + "sampler_name": "euler_ancestral", "scheduler": "karras", + "denoise": 1.0, "model": ["1", 0], + "positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0] + }}, + "6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}}, + "7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}} + } + + +def queue_prompt(workflow: dict) -> str: + try: + r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"sv_{uuid.uuid4().hex[:8]}"}) + return r.json().get("prompt_id") + except: + return None + + +def wait_completion(prompt_id: str, timeout: int = 300) -> bool: + start = time.time() + while time.time() - start < timeout: + try: + r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}") + if prompt_id in r.json() and r.json()[prompt_id].get("outputs"): + return True + except: + pass + time.sleep(2) + return False + + +def download_image(prompt_id: str, output_path: Path) -> bool: + try: + h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json() + for out in h.get(prompt_id, {}).get("outputs", {}).values(): + for img in out.get("images", []): + r = requests.get(f"{COMFYUI_URL}/view", params={"filename": img["filename"], "subfolder": img.get("subfolder", ""), "type": "output"}) + if r.status_code == 200: + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_bytes(r.content) + return True + return False + except: + return False + + +def main(): + print("=" * 70) + print("🌾 DOLINA SMRTI V6.3 - STARDEW VALLEY INDI STYLE") + print(" ¾ Top-down, Hand-drawn 2.5D, Full Body Characters") + print("=" * 70) + + try: + d = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5).json() + print(f"✅ ComfyUI v{d['system']['comfyui_version']} running") + except: + print(f"❌ ComfyUI not responding - start with: open /Applications/ComfyUI.app") + return + + print("\n📋 Building V6.3 Stardew Indi Registry...") + ASSETS = generate_v63_registry() + print(f"📊 Total: {len(ASSETS)} assets") + + # Count by category + cats = {} + for a in ASSETS: + cats[a["cat"]] = cats.get(a["cat"], 0) + 1 + print("\nPo kategorijah:") + for cat, count in sorted(cats.items(), key=lambda x: -x[1]): + print(f" {cat}: {count}") + + existing = sum(1 for a in ASSETS if (Path(OUTPUT_DIR) / a["cat"] / a["file"]).exists()) + print(f"\n✅ Exist: {existing} | 🎯 Generate: {len(ASSETS) - existing}") + + print("\n🌾 STARTING STARDEW VALLEY STYLE GENERATION...\n") + + success, skip, fail = 0, 0, 0 + + for i, asset in enumerate(ASSETS, 1): + path = Path(OUTPUT_DIR) / asset["cat"] / asset["file"] + + if path.exists(): + skip += 1 + continue + + print(f"[{i}/{len(ASSETS)}] 🌾 {asset['file'][:40]}...") + + wf = create_workflow(asset["prompt"], asset["file"].replace(".png", "")) + pid = queue_prompt(wf) + + if pid and wait_completion(pid) and download_image(pid, path): + print(f" ✅ SAVED") + success += 1 + else: + print(f" ❌ FAILED") + fail += 1 + + if i % 25 == 0: + print(f"\n📊 [{i}/{len(ASSETS)}] ✅{success} ⏭️{skip} ❌{fail}\n") + + time.sleep(0.5) + + print("\n" + "=" * 70) + print("🌾 STARDEW VALLEY STYLE GENERATION COMPLETE!") + print(f"✅ Success: {success} | ⏭️ Skip: {skip} | ❌ Fail: {fail}") + print(f"📁 Output: {OUTPUT_DIR}") + + +if __name__ == "__main__": + main()