Clean slate for style refinement

- Deleted all ComfyUI test images (not matching desired style)
- Added generate_v63_stardew.py (Stardew Valley style generator)
- User provided reference images for correct cartoon/vector style
- Ready for style adjustments based on Ana/Gronk/Susi references

Next: Refine prompts to match reference art style
This commit is contained in:
2025-12-28 23:46:20 +01:00
parent 349aa917db
commit 8a14ece2a2
20 changed files with 527 additions and 0 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

View File

@@ -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()