📝 Nočna Session Setup - Asset Generation Infrastructure

- Created overnight generation system
- Added master character references (Gronk, Kai)
- Implemented auto-commit for all generated assets
- Created comprehensive documentation and changelogs
- Setup FULL generator (850+ assets without NPCs)
- Added progress tracking and status check scripts

Ready for overnight mass generation 🌙
This commit is contained in:
2025-12-29 03:43:44 +01:00
parent 54d3aa3bbc
commit 117624befc
13 changed files with 1372 additions and 0 deletions

145
CHANGELOG_29_12_2025.md Normal file
View File

@@ -0,0 +1,145 @@
# 📝 Changelog - 29.12.2025
## 🌙 Nočna Session (03:00 - 09:00)
### **Glavna Aktivnost:**
Avtomatska generacija FULL asset set-a za DolinaSmrti
---
## ✅ Opravljeno:
### **1. Character Reference System**
- ✅ Upload master reference slik (Gronk, Kai)
- ✅ Kreiran `reference_images/` directory
- ✅ Dokumentacija v `CHARACTER_REFERENCES.md`
- ✅ NPCs izključeni iz avtomatske generacije
### **2. Test Generacije**
- ✅ Regeneriran Gronk walking frame (z master ref)
- ✅ Regeneriran Kai walking frame (z master ref)
- ✅ Test samples iz vsake kategorije
- ✅ Kvalitetni check - APPROVED
### **3. Generator Setup**
- ✅ Posodobljen `generate_local_final.py` z auto-commit
- ✅ Kreiran `test_category_samples.py`
- ✅ Kreiran `regenerate_with_master_ref.py`
- ✅ Kreiran `generate_full_auto.py` za FULL set
### **4. Automation Scripts**
-`run_auto_generation.sh` - background runner
-`check_generation_status.sh` - napredek checker
- ✅ Auto-commit functionality (Git)
- ✅ Auto-open images za review
### **5. Dokumentacija**
-`AUTO_GENERATION_README.md`
-`CHARACTER_REFERENCES.md`
-`NOCNA_GENERACIJA_LOG.md` (ta datoteka)
- ✅ Session changelog
---
## 🎯 V Teku:
### **FULL Asset Generation**
- **Start:** ~03:45
- **Target:** ~850 slik
- **Categories:** Buildings, Workstations, Items, Animals, Environment, Mutants, Bosses, UI
- **Excluded:** NPCs, Main Characters
- **ETA:** ~09:00 (5-6 ur)
---
## 📊 Statistika:
### **Pred Generacijo:**
- PNG slik: 150
- Git commits: ~50
### **Po Generaciji (target):**
- PNG slik: ~1,000
- Git commits: ~900
- Kategorij: 8
- Total MB: ~150-300 MB
---
## 🔧 Tehnični Detajli:
### **ComfyUI Setup:**
- Lokalni server: `127.0.0.1:8000`
- Model: Dreamshaper 8
- Version: 0.6.0
- Status: Running ✅
### **Processing:**
- Generation: ComfyUI workflow
- Background removal: rembg (u2net model)
- Format: PNG (transparent)
- Size: 512x512 (bosses 768x768)
---
## 🐛 Issues Fixed:
1. ✅ NPCs excluded iz automation (user request)
2. ✅ Master reference integration
3. ✅ Git auto-commit dodano
4. ✅ Progress tracking izboljšano
---
## 📅 Naslednji Koraki (Za Jutri):
### **Prioriteta 1: Review**
- [ ] Pregled vseh generiranih slik
- [ ] Kvalitetni check po kategorijah
- [ ] Identifikacija slab generiranih
### **Prioriteta 2: NPCs (Manual)**
- [ ] Pregled NPC lista
- [ ] Generacija z master reference style
- [ ] Review vsake slike posebej
### **Prioriteta 3: Assets Integration**
- [ ] Import v game
- [ ] Test v Tiled
- [ ] Animation sequences
---
## 💾 Backup Info:
**Git Status:**
- Branch: master
- Auto-commits: Enabled
- Remote: Ready for push
**Files Modified:**
- `scripts/generate_*.py` (multiple)
- `reference_images/*`
- `assets/images/*` (mass update)
---
## 🎨 Asset Breakdown:
| Category | Target | Status |
|:---|---:|:---|
| Buildings | 57 | Generira se |
| Workstations | 25 | Generira se |
| Items | 505 | Generira se |
| Animals | 147 | Generira se |
| Environment | 103 | Generira se |
| Mutants | 98 | Generira se |
| Bosses | 25 | Generira se |
| UI | 41 | Generira se |
| **TOTAL** | **1,001** | **V teku** |
---
**Last Updated:** 29.12.2025 03:43
**Next Review:** 29.12.2025 09:00 (zjutraj)
**Status:** 🟢 RUNNING

154
NOCNA_GENERACIJA_LOG.md Normal file
View File

@@ -0,0 +1,154 @@
# 🌙 NOČNA GENERACIJA - Session Log
**Datum:** 29. December 2025, 03:42
**Status:** AVTOMATSKA GENERACIJA V TEKU
---
## 📋 ČE BERETE TO ZJUTRAJ:
Pozdravljen! Tukaj je kratek pregled kaj je bilo narejeno med spanjem.
---
## 🎯 CILJ NOČNE GENERACIJE:
**FULL Asset Set** - ~850 slik (BREZ NPCs in glavnih karakterjev)
### **Vključeno:**
-**Buildings** (57) - Farm, Production, Town buildings
-**Workstations** (25) - Crafting stations
-**Items** (505) - Tools, weapons, potions, food
-**Animals** (147) - Farm, wildlife, legendary
-**Environment** (103) - Trees, objects, terrain
-**Mutanti** (98) - Zombies, slimes
-**Bosses** (25) - Epic encounters
-**UI** (41) - Interface elements
### **IZKLJUČENO:**
- ❌ NPCs (~85)
- ❌ Main Characters (Gronk, Kai, Ana)
---
## 📊 PRED GENERACIJO:
**Že generirano:** 150 PNG slik
**Cilj:** ~1,000 PNG slik (FULL set brez NPCs)
**Manjka:** ~850 slik
---
## ⏱️ ČASOVNI OKVIR:
**Ocena:** 5-6 ur
**Start:** 29.12.2025 ~03:45
**Predviden konec:** 29.12.2025 ~09:00
---
## 🔧 TEHNIČNI DETAJLI:
### **Generator:**
- Script: `generate_full_auto.py`
- ComfyUI: Local port 8000
- Model: Dreamshaper 8
- Background removal: rembg (u2net)
- Auto-commit: DA (vsaka slika)
### **Konfiguratcija:**
- Size: 512x512 (bosses 768x768)
- Steps: 30
- CFG: 7.5
- Sampler: euler_ancestral
- Scheduler: karras
---
## 📁 OUTPUT:
Vse slike v:
```
/Users/davidkotnik/repos/novafarma/assets/images/
├── items/
├── buildings/
├── workstations/
├── environment/
├── zivali/
├── mutanti/
├── bosses/
└── ui/
```
---
## 📝 GIT COMMITS:
Vsaka slika se avtomatsko committa:
```
🎨 Auto-generated: [category]/[filename]
```
---
## 🔍 KAKO PREVERITI NAPREDEK:
### **1. Pregled logov:**
```bash
cat /Users/davidkotnik/repos/novafarma/generation_progress.log
```
### **2. Status check:**
```bash
cd /Users/davidkotnik/repos/novafarma/scripts
./check_generation_status.sh
```
### **3. Štetje slik:**
```bash
find /Users/davidkotnik/repos/novafarma/assets/images -name "*.png" | wc -l
```
---
## ✅ ČE JE VSE OK:
Pričakujete:
- **~1,000 PNG slik** v `/assets/images/`
- **~850 Git commits**
- **Vse transparentne** (rembg processed)
- **Organizirano po kategorijah**
---
## ❌ ČE NEKAJ NI V REDU:
Preverite:
1. `generation_progress.log` - za errore
2. ComfyUI je še vedno running
3. Disk space (vsaka slika ~100-300 KB)
---
## 🎨 MASTER REFERENCES:
**Važno:** NPCs ostanejo ročno, ker uporabljamo master reference:
- `reference_images/MASTER_GRONK.png`
- `reference_images/MASTER_KAI.png`
---
## 📈 NASLEDNJI KORAKI (za zjutraj):
1. ✅ Pregled kvalitete slik
2. ✅ Če je OK → lahko začnemo z NPCs (ročno)
3. ✅ Če ni OK → debug in ponovna generacija
---
**Generated:** 29.12.2025 03:42
**By:** Antigravity AI Assistant
**Purpose:** Overnight mass asset generation for DolinaSmrti game
---
**Lep počitek in pohvale za jutro!** 🌟

View File

@@ -0,0 +1,80 @@
# 🎨 MASTER CHARACTER REFERENCES
These are the **DEFINITIVE** character designs. ALL generated assets MUST match these exact styles.
## 🧌 GRONK - Master Reference
![Gronk Master](MASTER_GRONK.png)
**Key Features:**
- **Skin**: Green-grey, visible belly
- **Hair**: BRIGHT PINK dreadlocks with ear gauges
- **Face**: Piercings (nose ring, ear piercings), peaceful zen expression
- **Clothing**:
- Black t-shirt with "TROLL SABBATH" purple text
- Black baggy pants (loose fit)
- PINK sneakers (bright magenta)
- **Props**: Colorful vape device with pink/purple smoke
- **Body**: Large, overweight, relaxed posture
**Exact Prompt Template:**
```
Gronk the troll character, green-grey skin with visible round belly,
BRIGHT PINK dreadlocks, large ear gauges, nose ring and facial piercings,
wearing black baggy t-shirt with purple "TROLL SABBATH" text,
black loose baggy pants, bright pink sneakers,
holding colorful rainbow vape device with pink smoke,
peaceful relaxed expression, full body
```
---
## 👤 KAI - Master Reference
![Kai Master](MASTER_KAI.png)
**Key Features:**
- **Skin**: Medium tone, clean
- **Hair**: DARK GREEN thick dreadlocks (forest green, not lime)
- **Face**: Ear gauges (stretched lobes), nose piercing, lip piercing, serious expression
- **Clothing**:
- Blue-grey weathered denim jacket (dirt stains, wear marks)
- Beige/tan undershirt
- Ripped blue jeans (torn at knees)
- Brown leather combat boots (laced up)
- Brown survival backpack with pockets and straps
- **Build**: Teenage, athletic, lean
- **Posture**: Determined, survivor stance
**Exact Prompt Template:**
```
Kai teenage survivor character, dark forest green thick dreadlocks,
medium skin tone, large ear gauges, nose piercing and lip piercing,
serious determined expression,
wearing weathered blue-grey denim jacket with dirt stains,
beige t-shirt underneath,
torn blue jeans ripped at knees,
brown leather combat boots,
brown survival backpack with straps and pockets,
athletic lean build, full body
```
---
## 🎯 USAGE INSTRUCTIONS
1. **All Gronk animations** must use the Gronk template
2. **All Kai animations** must use the Kai template
3. **Color accuracy is critical**:
- Gronk's pink = `#FF1493` (bright magenta)
- Kai's green = `#2D5016` (dark forest green)
4. **Include ALL details** - piercings, clothing text, wear/dirt
5. **Match proportions** - Gronk is wide/heavy, Kai is lean/athletic
---
## 📝 REGENERATION NEEDED
The following files were generated BEFORE these references and need regeneration:
- `npcs/gronk_front_walk1.png`
- `npcs/kai_front_walk1.png`
Delete and regenerate with correct prompts.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

View File

@@ -0,0 +1,124 @@
# 🎮 DOLINA SMRTI - Avtomatska Generacija Assetsov
## 🚀 NAČIN 1: Popolnoma Avtomatsko (PRIPOROČENO)
### Zagon:
```bash
cd /Users/davidkotnik/repos/novafarma/scripts
./run_auto_generation.sh
```
**To bo:**
- ✅ Zagnalo generacijo v ozadju
- ✅ Kreiral log datoteko z timestampom
- ✅ Omogočil da zaprete terminal ALI greste spat
- ✅ ComfyUI že teče, zato bo začel takoj
**Po zagonu lahko:**
- Zaprete terminal - proces bo tekel naprej
- Ugasnete zaslon - proces bo tekel naprej
- Greste spat - proces bo tekel naprej
---
## 📊 Spremljanje Napredka
### Preveri status:
```bash
./check_generation_status.sh
```
### Live spremljanje (real-time):
```bash
tail -f /Users/davidkotnik/repos/novafarma/generation_*.log
```
Za izhod iz live pogleda: **Ctrl+C**
---
## ⏹️ Ustavitev Generacije
Če želite ustaviti:
```bash
kill $(cat /tmp/dolina_generation.pid)
```
---
## 🚀 NAČIN 2: Terminal Session (za debugging)
Če želite videti output v realnem času:
```bash
cd /Users/davidkotnik/repos/novafarma/scripts
python3 generate_local_final.py
```
---
## ⏱️ Časovni Okvir
**Na podlagi testov:**
- ⏱️ ~15-30 sekund na asset
- 📊 **110 remaining assets** = ~45-90 minut
- 📊 **422 total V7 assets** = ~3-5 ur
- 📊 **1,418 full assets** = ~10-18 ur
**Ker ComfyUI teče lokalno:**
- ❌ BREZ API rate limitov
- ❌ BREZ pavz
- ❌ BREZ potrebe po vaši prisotnosti
- ✅ Lahko teče ČEZNOJI
---
## 📁 Rezultati
Vsi generirani PNG-ji so avtomatsko:
- ✅ Odstranjeno ozadje (transparentni)
- ✅ Shranjeni v `/Users/davidkotnik/repos/novafarma/assets/images/`
- ✅ Razvrščeni po kategorijah
---
## 🔧 Možne Težave
### ComfyUI se ne odziva:
1. Odprite ComfyUI app
2. Počakajte da se zažene (zeleni indikator)
3. Poskusite znova
### Generacija se ne začne:
```bash
# Preverite error log:
cat /Users/davidkotnik/repos/novafarma/generation_*.log
```
---
## 💡 Nasveti
**ZA ČEZ NOČ:**
1. Zaženite: `./run_auto_generation.sh`
2. Greste spat 😴
3. Zjutraj: `./check_generation_status.sh`
4. Profit! 🎉
**ZA PREMIUM REZULTATE:**
- ComfyUI uporablja **Dreamshaper 8** model
- Vsaka slika je **512x512** (bosses 768x768)
- Background removal z **rembg (u2net model)**
- **30 generation steps** za kakovost
---
## 📈 Trenutni Status
Po zadnjem preverjanju:
- ✅ ComfyUI: **v teku** (port 8000)
- 📊 Generirano: **148/422** (V7) ali **148/1,418** (FULL)
- ⏳ Manjka: **~274 slik** za V7 set
---
**🎯 Glavna Prednost: Lahko vse teče AVTOMATSKO čez noč!** 🌙

View File

@@ -0,0 +1,49 @@
#!/bin/bash
# 🔍 Preveri status generacije
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🎮 DOLINA SMRTI - Asset Generation Status"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Preveri če proces teče
if [ -f /tmp/dolina_generation.pid ]; then
PID=$(cat /tmp/dolina_generation.pid)
if ps -p $PID > /dev/null 2>&1; then
echo "✅ Generacija TEČE (PID: $PID)"
# Pokaži zadnje loge
LATEST_LOG=$(ls -t /Users/davidkotnik/repos/novafarma/generation_*.log 2>/dev/null | head -1)
if [ -n "$LATEST_LOG" ]; then
echo "📂 Log file: $LATEST_LOG"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Zadnjih 15 vrstic:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tail -15 "$LATEST_LOG"
fi
else
echo "❌ Proces NE teče več (PID $PID ni aktiven)"
rm /tmp/dolina_generation.pid
fi
else
echo "⭕ Generacija NI zagnana"
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📁 Trenutno generirane slike:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd /Users/davidkotnik/repos/novafarma/assets/images
for dir in */; do
count=$(find "$dir" -name "*.png" 2>/dev/null | wc -l)
printf " %-20s: %3d slik\n" "${dir%/}" "$count"
done
total=$(find . -name "*.png" 2>/dev/null | wc -l)
echo " ────────────────────────────────"
printf " %-20s: %3d slik\n" "SKUPAJ" "$total"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

161
scripts/fresh_test.py Normal file
View File

@@ -0,0 +1,161 @@
#!/usr/bin/env python3
"""
🚀 FRESH TEST - Generira 3 nove slike ki jih še ni
"""
import os
import sys
import json
import time
import uuid
import requests
import subprocess
from pathlib import Path
from datetime import datetime
try:
from rembg import remove
from PIL import Image
except ImportError:
print("📦 Installing rembg...")
os.system("pip3 install --user rembg pillow onnxruntime")
from rembg import remove
from PIL import Image
# Configuration
COMFYUI_URL = "http://127.0.0.1:8000"
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible, isolated on pure white background"
NEGATIVE = "pixel art, pixelated, 3d, realistic, photo, blurry, watermark, text, green background"
# 🆕 NOVE SLIKE - Še ne generirane
NEW_ASSETS = [
("npcs", "gronk_front_walk1", "Gronk massive troll, PINK dreadlocks, black baggy t-shirt and pants, pink sneakers, holding vape, front view walking left leg forward"),
("npcs", "kai_front_walk1", "Kai teenage survivor, GREEN dreadlocks, blue jacket, torn jeans, boots, front view walking left leg forward"),
("zivali", "fox_red", "red fox wildlife animal, bushy tail, clever expression, side view"),
]
def log(msg):
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] {msg}")
sys.stdout.flush()
def git_commit(file_path, category, name):
"""Auto-commit generated asset"""
try:
rel_path = file_path.relative_to(REPO_DIR)
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
subprocess.run(["git", "commit", "-m", f"🎨 Generated: {category}/{name}"], cwd=REPO_DIR, check=True, capture_output=True)
log(f" 📝 Git committed: {rel_path}")
return True
except:
return False
def create_workflow(prompt_text, output_name, size=512):
seed = int(time.time() * 1000) % 2147483647
full_prompt = f"{STYLE}, {prompt_text}"
return {
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "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):
try:
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"}, timeout=10)
return r.json().get("prompt_id")
except Exception as e:
log(f"❌ Queue error: {e}")
return None
def wait_completion(prompt_id, timeout=120):
start = time.time()
while time.time() - start < timeout:
try:
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
return True
except:
pass
time.sleep(2)
return False
def download_and_process(prompt_id, output_path):
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)
from io import BytesIO
transparent_img = remove(Image.open(BytesIO(r.content)))
transparent_img.save(str(output_path), "PNG")
return True
return False
except Exception as e:
log(f"❌ Download error: {e}")
return False
def main():
log("="*60)
log("🚀 FRESH TEST - Generiranje Novih Slik")
log(" Z avtomatskim Git commitom")
log("="*60)
try:
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']} running")
except:
log("❌ ComfyUI not running!")
return
log(f"\n🎯 Generating {len(NEW_ASSETS)} new assets...\n")
for i, (cat, name, prompt) in enumerate(NEW_ASSETS, 1):
path = OUTPUT_DIR / cat / f"{name}.png"
if path.exists():
log(f"[{i}/{len(NEW_ASSETS)}] ⏭️ {name} - skipping (exists)")
continue
log(f"[{i}/{len(NEW_ASSETS)}] 🎨 {name}...")
wf = create_workflow(prompt, name, 512)
pid = queue_prompt(wf)
if pid and wait_completion(pid) and download_and_process(pid, path):
log(f" ✅ Generated & transparent!")
git_commit(path, cat, name)
else:
log(f" ❌ FAILED")
log("\n" + "="*60)
log("🚀 FRESH TEST COMPLETE!")
log("="*60)
if __name__ == "__main__":
main()

View File

@@ -11,6 +11,7 @@ import json
import time import time
import uuid import uuid
import requests import requests
import subprocess
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
@@ -116,6 +117,40 @@ def log(msg):
sys.stdout.flush() sys.stdout.flush()
def git_commit(file_path, category, name):
"""Auto-commit generated asset to Git"""
try:
repo_dir = Path("/Users/davidkotnik/repos/novafarma")
rel_path = file_path.relative_to(repo_dir)
# Git add
subprocess.run(
["git", "add", str(rel_path)],
cwd=repo_dir,
check=True,
capture_output=True
)
# Git commit
commit_msg = f"🎨 Auto-generated asset: {category}/{name}"
result = subprocess.run(
["git", "commit", "-m", commit_msg],
cwd=repo_dir,
capture_output=True,
text=True
)
if result.returncode == 0:
log(f" 📝 Git committed")
return True
else:
# Možno da je že committed ali ni sprememb
return False
except Exception as e:
log(f" ⚠️ Git: {str(e)[:50]}")
return False
def create_workflow(prompt_text, output_name, size=512): def create_workflow(prompt_text, output_name, size=512):
"""Create ComfyUI workflow""" """Create ComfyUI workflow"""
seed = int(time.time() * 1000) % 2147483647 seed = int(time.time() * 1000) % 2147483647
@@ -271,6 +306,8 @@ def main():
if pid and wait_completion(pid) and download_and_process(pid, path): if pid and wait_completion(pid) and download_and_process(pid, path):
log(f" ✅ DONE (transparent)") log(f" ✅ DONE (transparent)")
# Auto-commit to Git
git_commit(path, cat, name)
success += 1 success += 1
else: else:
log(f" ❌ FAILED") log(f" ❌ FAILED")

View File

@@ -0,0 +1,175 @@
#!/usr/bin/env python3
"""
🎨 REGENERATE - Z Master Reference
Uporablja točne specifikacije iz MASTER_GRONK.png in MASTER_KAI.png
"""
import os
import sys
import json
import time
import uuid
import requests
import subprocess
from pathlib import Path
from datetime import datetime
try:
from rembg import remove
from PIL import Image
except ImportError:
os.system("pip3 install --user rembg pillow onnxruntime")
from rembg import remove
from PIL import Image
COMFYUI_URL = "http://127.0.0.1:8000"
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
STYLE = "2D indie game cartoon character sprite, clean vector style, smooth bold outlines, full body visible head to feet, isolated on pure white background"
NEGATIVE = "pixel art, pixelated, 3d render, realistic photo, anime, manga, blurry, watermark, text, green background, cut off"
# 🎯 CORRECT PROMPTS based on MASTER references
CORRECT_ASSETS = [
("npcs", "gronk_front_walk1",
"Gronk the troll character, green-grey skin with visible round belly, "
"BRIGHT PINK dreadlocks, large ear gauges, nose ring and facial piercings, "
"wearing black baggy t-shirt with purple TROLL SABBATH text, "
"black loose baggy pants, bright pink sneakers, "
"holding colorful rainbow vape device with pink smoke, "
"peaceful relaxed expression, full body, front view, walking pose left leg forward"),
("npcs", "kai_front_walk1",
"Kai teenage survivor character, dark forest green thick dreadlocks, "
"medium skin tone, large ear gauges, nose piercing and lip piercing, "
"serious determined expression, "
"wearing weathered blue-grey denim jacket with dirt stains, "
"beige t-shirt underneath, "
"torn blue jeans ripped at knees, "
"brown leather combat boots, "
"brown survival backpack with straps and pockets, "
"athletic lean build, full body, front view, walking pose left leg forward"),
]
def log(msg):
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] {msg}")
sys.stdout.flush()
def git_commit(file_path, category, name):
try:
rel_path = file_path.relative_to(REPO_DIR)
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
subprocess.run(["git", "commit", "-m", f"🎨 CORRECT: {category}/{name} (master ref)"], cwd=REPO_DIR, check=True, capture_output=True)
log(f" 📝 Git committed with master ref tag")
return True
except:
return False
def create_workflow(prompt_text, output_name, size=512):
seed = int(time.time() * 1000) % 2147483647
full_prompt = f"{STYLE}, {prompt_text}"
return {
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}},
"5": {
"class_type": "KSampler",
"inputs": {
"seed": seed, "steps": 35, "cfg": 8.0,
"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):
try:
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"regen_{uuid.uuid4().hex[:8]}"}, timeout=10)
return r.json().get("prompt_id")
except Exception as e:
log(f"❌ Queue error: {e}")
return None
def wait_completion(prompt_id, timeout=120):
start = time.time()
while time.time() - start < timeout:
try:
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
return True
except:
pass
time.sleep(2)
return False
def download_and_process(prompt_id, output_path):
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)
from io import BytesIO
transparent_img = remove(Image.open(BytesIO(r.content)))
transparent_img.save(str(output_path), "PNG")
return True
return False
except Exception as e:
log(f"❌ Download error: {e}")
return False
def main():
log("="*70)
log("🎨 REGENERATE - Z Master Reference Slikami")
log(" Točne specifikacije iz MASTER_GRONK.png & MASTER_KAI.png")
log("="*70)
try:
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']} running")
except:
log("❌ ComfyUI not running!")
return
log(f"\n🎯 Regenerating {len(CORRECT_ASSETS)} characters with CORRECT style...\n")
for i, (cat, name, prompt) in enumerate(CORRECT_ASSETS, 1):
path = OUTPUT_DIR / cat / f"{name}.png"
log(f"[{i}/{len(CORRECT_ASSETS)}] 🎨 {name}...")
log(f" 📋 Using master reference prompt")
wf = create_workflow(prompt, name, 512)
pid = queue_prompt(wf)
if pid and wait_completion(pid) and download_and_process(pid, path):
log(f" ✅ Generated with CORRECT style!")
git_commit(path, cat, name)
# Auto-open to verify
os.system(f"open {path}")
else:
log(f" ❌ FAILED")
log("\n" + "="*70)
log("🎨 REGENERATION COMPLETE!")
log(" Slike so odprte - preverite ali sedaj ustrezajo!")
log("="*70)
if __name__ == "__main__":
main()

37
scripts/run_auto_generation.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# 🎮 DOLINA SMRTI - Avtomatski generator
# Teče v ozadju, logs v datoteko
cd /Users/davidkotnik/repos/novafarma/scripts
# Kreiraj log file z timestampom
LOG_FILE="/Users/davidkotnik/repos/novafarma/generation_$(date +%Y%m%d_%H%M%S).log"
echo "🎮 Starting DOLINA SMRTI Asset Generation..."
echo "📂 Logs: $LOG_FILE"
echo "⏱️ Start time: $(date)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "🔥 Generation je v teku... lahko zaprete terminal ali pustite račun vklopljen."
echo " Za preverjanje statusa: tail -f $LOG_FILE"
echo ""
# Zaženi generacijo v ozadju z logs
nohup python3 generate_local_final.py > "$LOG_FILE" 2>&1 &
# Shrani PID
PID=$!
echo "✅ Process ID: $PID"
echo "$PID" > /tmp/dolina_generation.pid
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Za spremljanje napredka (live):"
echo " tail -f $LOG_FILE"
echo ""
echo "⏹️ Za ustavitev generacije:"
echo " kill $PID"
echo ""
echo "🎯 Ko je končano, rezultat bo v:"
echo " /Users/davidkotnik/repos/novafarma/assets/images/"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

View File

@@ -0,0 +1,201 @@
#!/usr/bin/env python3
"""
🧪 CATEGORY TEST SAMPLES
Po 1 stvar iz vsake kategorije - kvalitetni check pred množično generacijo
"""
import os
import sys
import json
import time
import uuid
import requests
import subprocess
from pathlib import Path
from datetime import datetime
try:
from rembg import remove
from PIL import Image
except ImportError:
os.system("pip3 install --user rembg pillow onnxruntime")
from rembg import remove
from PIL import Image
COMFYUI_URL = "http://127.0.0.1:8000"
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
STYLE = "2D indie game sprite, cartoon vector style, clean smooth outlines, full body visible, isolated on pure white background"
NEGATIVE = "pixel art, pixelated, 3d render, realistic photo, anime, blurry, watermark, text, green background"
# 🧪 TEST SAMPLES - Po 1 iz vsake kategorije (BREZ NPCs!)
TEST_SAMPLES = [
# Živali
("zivali", "rabbit_white", "white rabbit animal, long ears, fluffy tail, cute, side view"),
# Bosses
("bosses", "boss_dragon_ice", "Ice Dragon boss, massive blue dragon, frost breath, ice scales, menacing, full body"),
# Items - Tool
("items", "tool_pickaxe_iron", "iron pickaxe tool, metal head, wooden handle, mining equipment"),
# Items - Weapon
("items", "weapon_bow_wood", "wooden bow with arrow, hunting weapon, medieval style"),
# Items - Magic
("items", "wand_lightning", "lightning magic wand, yellow crystal tip, electric sparks, glowing"),
# Items - Potion
("items", "potion_mana", "mana potion, blue liquid in glass bottle, magical glow"),
# Items - Food
("items", "food_bread", "bread loaf, fresh baked, brown crust, artisan style"),
# Environment - Tree
("environment", "tree_pine", "pine tree, evergreen, cone shaped, forest tree, full tree"),
# Environment - Object
("environment", "barrel_wood", "wooden storage barrel, medieval style, brown wood"),
# Mutanti
("mutanti", "slime_purple", "purple poison slime monster, bouncing blob, toxic bubbles"),
]
def log(msg):
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] {msg}")
sys.stdout.flush()
def git_commit(file_path, category, name):
try:
rel_path = file_path.relative_to(REPO_DIR)
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
subprocess.run(["git", "commit", "-m", f"🧪 Test sample: {category}/{name}"], cwd=REPO_DIR, check=True, capture_output=True)
log(f" 📝 Committed")
return True
except:
return False
def create_workflow(prompt_text, output_name, size=512):
seed = int(time.time() * 1000) % 2147483647
full_prompt = f"{STYLE}, {prompt_text}"
return {
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "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):
try:
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"}, timeout=10)
return r.json().get("prompt_id")
except Exception as e:
log(f"{e}")
return None
def wait_completion(prompt_id, timeout=120):
start = time.time()
while time.time() - start < timeout:
try:
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
return True
except:
pass
time.sleep(2)
return False
def download_and_process(prompt_id, output_path):
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)
from io import BytesIO
transparent_img = remove(Image.open(BytesIO(r.content)))
transparent_img.save(str(output_path), "PNG")
return True
return False
except Exception as e:
log(f"{e}")
return False
def main():
log("="*70)
log("🧪 CATEGORY TEST SAMPLES")
log(" Po 1 iz vsake kategorije - kvalitetni check")
log(" NPCs IZKLJUČENI iz avtomatike!")
log("="*70)
try:
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']}")
except:
log("❌ ComfyUI not running!")
return
log(f"\n🎯 Generating {len(TEST_SAMPLES)} test samples...\n")
success = 0
for i, (cat, name, prompt) in enumerate(TEST_SAMPLES, 1):
path = OUTPUT_DIR / cat / f"{name}.png"
if path.exists():
log(f"[{i}/{len(TEST_SAMPLES)}] ⏭️ {name} - exists")
continue
log(f"[{i}/{len(TEST_SAMPLES)}] 🎨 {cat}/{name}")
size = 768 if cat == "bosses" else 512
wf = create_workflow(prompt, name, size)
pid = queue_prompt(wf)
if pid and wait_completion(pid) and download_and_process(pid, path):
log(f" ✅ Done!")
git_commit(path, cat, name)
success += 1
# Open image immediately for review
os.system(f"open {path}")
else:
log(f" ❌ Failed")
# Brief pause between generations
if i < len(TEST_SAMPLES):
time.sleep(2)
log("\n" + "="*70)
log(f"🧪 TEST SAMPLES COMPLETE! ({success}/{len(TEST_SAMPLES)})")
log(" Slike so odprte - preverite kakovost!")
log("="*70)
log("\n💡 Če je kakovost OK → lahko zaženem VSE ostale")
log(" (items, environment, animals, bosses, mutants)")
log(" NPCs ostanejo ROČNO!")
if __name__ == "__main__":
main()

209
scripts/test_generation.py Executable file
View File

@@ -0,0 +1,209 @@
#!/usr/bin/env python3
"""
🧪 TEST GENERATION - Generira 5 testnih slik
Z avtomatskim Git commitom
"""
import os
import sys
import json
import time
import uuid
import requests
import subprocess
from pathlib import Path
from datetime import datetime
try:
from rembg import remove
from PIL import Image
except ImportError:
print("📦 Installing rembg...")
os.system("pip3 install --user rembg pillow onnxruntime")
from rembg import remove
from PIL import Image
# Configuration
COMFYUI_URL = "http://127.0.0.1:8000"
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible, isolated on pure white background #FFFFFF"
NEGATIVE = "pixel art, pixelated, 3d, realistic, photo, blurry, watermark, text, green background"
# 🧪 TEST ASSETS - Par hitrih testnih slik
TEST_ASSETS = [
("npcs", "npc_elder", "wise tribal elder NPC, walking stick, long white beard, robes"),
("npcs", "npc_child", "survivor orphan child NPC, oversized clothes, teddy bear"),
("zivali", "goat_brown", "brown goat farm animal, small horns, playful"),
("items", "tool_hammer", "hammer building tool, wooden handle"),
("environment", "flower_red", "red flowers patch, blooming"),
]
def log(msg):
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] {msg}")
sys.stdout.flush()
def git_commit(file_path, category, name):
"""Auto-commit generated asset"""
try:
rel_path = file_path.relative_to(REPO_DIR)
# Git add
subprocess.run(
["git", "add", str(rel_path)],
cwd=REPO_DIR,
check=True,
capture_output=True
)
# Git commit
commit_msg = f"🎨 Generated asset: {category}/{name}"
subprocess.run(
["git", "commit", "-m", commit_msg],
cwd=REPO_DIR,
check=True,
capture_output=True
)
log(f" ✅ Git committed: {rel_path}")
return True
except subprocess.CalledProcessError as e:
log(f" ⚠️ Git commit failed (možno že committed): {e}")
return False
def create_workflow(prompt_text, output_name, size=512):
seed = int(time.time() * 1000) % 2147483647
full_prompt = f"{STYLE}, {prompt_text}"
return {
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "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):
try:
r = requests.post(
f"{COMFYUI_URL}/prompt",
json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"},
timeout=10
)
return r.json().get("prompt_id")
except Exception as e:
log(f"❌ Queue error: {e}")
return None
def wait_completion(prompt_id, timeout=120):
start = time.time()
while time.time() - start < timeout:
try:
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
data = r.json()
if prompt_id in data and data[prompt_id].get("outputs"):
return True
except:
pass
time.sleep(2)
return False
def download_and_process(prompt_id, output_path):
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)
# Remove background
from io import BytesIO
src_img = Image.open(BytesIO(r.content))
transparent_img = remove(src_img)
transparent_img.save(str(output_path), "PNG")
return True
return False
except Exception as e:
log(f"❌ Download error: {e}")
return False
def main():
log("=" * 60)
log("🧪 TEST GENERATION - 5 Testnih Slik")
log(" Z avtomatskim Git commitom")
log("=" * 60)
# Check ComfyUI
try:
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
v = r.json()["system"]["comfyui_version"]
log(f"✅ ComfyUI v{v} running")
except:
log("❌ ComfyUI not running!")
return
log(f"\n🎯 Generating {len(TEST_ASSETS)} test assets...\n")
success, fail = 0, 0
start_time = time.time()
for i, (cat, name, prompt) in enumerate(TEST_ASSETS, 1):
path = OUTPUT_DIR / cat / f"{name}.png"
# Skip if exists
if path.exists():
log(f"[{i}/{len(TEST_ASSETS)}] ⏭️ {name} - already exists")
continue
log(f"[{i}/{len(TEST_ASSETS)}] 🎨 Generating {name}...")
wf = create_workflow(prompt, name, 512)
pid = queue_prompt(wf)
if pid and wait_completion(pid) and download_and_process(pid, path):
log(f" ✅ Image saved (transparent)")
# Auto-commit
git_commit(path, cat, name)
success += 1
else:
log(f" ❌ FAILED")
fail += 1
elapsed = time.time() - start_time
log("\n" + "=" * 60)
log("🧪 TEST COMPLETE!")
log(f" ✅ Success: {success}")
log(f" ❌ Failed: {fail}")
log(f" ⏱️ Time: {elapsed:.1f}s ({elapsed/60:.1f} min)")
log(f" 📁 Output: {OUTPUT_DIR}")
log("=" * 60)
if __name__ == "__main__":
main()