📚 Documentation + scripts from today's exploration

- ASSET_COUNT_STATUS_01_01_2026.md - asset tracking
- CHARACTER_PRODUCTION_PLAN.md - character animation plan
- CHARACTER_GENERATION_FINAL_PLAN.md - API alternatives research
- COMFYUI_SETUP_TODAY.md - ComfyUI setup guide
- TASKS_01_01_2026.md - consolidated task list
- FULL_STORY_OVERVIEW.md - game narrative summary
- preview_animations.html - animation preview gallery
- Test scripts for API exploration (test_minimal.py, test_imagen.py)
- Character generation scripts (generate_all_characters_complete.py, generate_characters_working.py)

These were created during API troubleshooting and production planning.
This commit is contained in:
2026-01-01 18:29:50 +01:00
parent fbe6d8cb90
commit a101d49f2e
11 changed files with 2714 additions and 0 deletions

View File

@@ -0,0 +1,289 @@
# 📊 ASSET COUNT STATUS - 1.1.2026
**Datum**: 1.1.2026 @ 12:45
**Trenutno**: 752 PNG
**Target**: 13,500 PNG
**Progress**: 5.6%
---
## 📈 TRENUTNO STANJE
| Kategorija | PNG Files | % Complete | Status |
|:-----------|----------:|:----------:|:------:|
| **kai** | 265 | ✅ | Animations complete |
| **ana** | 15 | 🟡 | Need animations |
| **gronk** | 14 | 🟡 | Need animations |
| **npcs** | 48 | 🔴 | Need 132 more |
| **sovrazniki** | 68 | 🔴 | Need more zombies |
| **zgradbe** | 16 | 🔴 | Need 150+ |
| **orodja** | 10 | 🟡 | Need upgrades |
| **hrana** | 10 | 🔴 | Need 100+ |
| **orozje** | 10 | 🔴 | Need 50+ |
| **rastline** | 71 | 🟡 | Need seasonal |
| **ui** | 24 | 🟡 | Need 200+ |
| **dinozavri** | 32 | ✅ | COMPLETE! |
| **ostalo** | 169 | 🔴 | Misc assets |
| **TOTAL** | **752** | **5.6%** | 🚀 **Production Active** |
---
## 🧟 GLAVNI KARAKTERJI + SOVRAŽNIKI - PODROBNO
### 👥 Heroes (Main Characters)
| Karakter | PNG Files | Status | Lokacija |
|:---------|----------:|:------:|:---------|
| **Kai** | 1 | 🔴 MASTER ONLY | `assets/slike/kai/MASTER_KAI.png` |
| **Ana** | 0 | 🔴 NEED MASTER | `assets/slike/ana/` |
| **Gronk** | 1 | 🔴 MASTER ONLY | `assets/slike/gronk/` |
| **konsistentno/** | 6 | ✅ LOCKED REFS | Style A + B (all 3) |
| **Heroes Total** | **8** | 🔴 **NEED ~174 ANIMATIONS** | - |
#### 🎬 Animations Needed:
| Character | Walk Cycle | Idle | Actions | Tools | TOTAL Needed |
|:----------|:----------:|:----:|:-------:|:-----:|-----------:|
| Kai | 32 PNG | 4 | 12 | 8 | +56 PNG |
| Ana | 32 PNG | 4 | 12 | 12 | +60 PNG |
| Gronk | 32 PNG | 4 | 16 | 6 | +58 PNG |
| **TOTAL** | **96** | **12** | **40** | **26** | **+174 PNG** |
---
### 🧟 Zombies & Enemies
| Category | PNG Files | 1024px | 256px | Status | Lokacija |
|:---------|----------:|:------:|:-----:|:------:|:---------|
| **Zombiji** | 36 | 18 | 18 | 🟡 BASIC SET | `sovrazniki/zombiji/` |
| **Mutanti** | 6 | 3 | 3 | 🔴 NEED MORE | `sovrazniki/mutanti/` |
| **Bossi** | 26 | 13 | 13 | 🟡 GOOD START | `sovrazniki/bossi/` |
| **Enemies Total** | **68** | **34** | **34** | 🟡 **~23% Complete** | - |
#### 🧟 Zombie Types (36 PNG):
| Type | Count | Status |
|:-----|:-----:|:------:|
| Basic Zombies | ~18 | ✅ Core set |
| Zombie Variants | ~18 | 🟡 Previews |
| **NEED**: Animations | +144 | 🔴 Walk/Attack cycles |
| **NEED**: Hybrids | +50 | 🔴 Special types |
| **Target Total** | **230** | 🔴 **84% remaining** |
#### 🐾 Mutants (6 PNG):
- ✅ Mutant Spider (2 PNG - 1024 + 256)
- ✅ Mutant Dog (2 PNG - 1024 + 256)
- ✅ Mutant Rat Giant (2 PNG - 1024 + 256)
- ❌ NEED: +44 PNG (more mutant types + animations)
- **Target**: 50 PNG total
#### 👹 Bosses (26 PNG):
- ✅ Boss Dragon Fire (2 PNG)
- ✅ Boss Dragon Ice (2 PNG)
- ✅ Boss Phoenix (2 PNG)
- ✅ Boss Vampire (2 PNG)
- ✅ Boss Hydra (2 PNG)
- ✅ Boss Kraken (2 PNG)
- ✅ Boss Golem (2 PNG)
- ✅ Boss Spider Queen (2 PNG)
- ✅ Boss Demon (2 PNG)
- ✅ Boss T-Rex (2 PNG)
- ✅ +3 more bosses (6 PNG)
- ❌ NEED: +54 PNG (animations + 7 more bosses)
- **Target**: 80 PNG total (20 bosses × 4 PNG each)
---
## 📊 ENEMIES - PRODUCTION TARGET
| Category | Current | Today | Target | Remaining | Priority |
|:---------|--------:|------:|-------:|----------:|:--------:|
| **Zombies** | 36 | - | 230 | 194 | 🔥 HIGH |
| **Mutants** | 6 | - | 50 | 44 | 🔶 MEDIUM |
| **Bosses** | 26 | +20? | 80 | 54 | 🔷 MEDIUM |
| **Hybrids** | 0 | - | 100 | 100 | 🔵 LOW |
| **TOTAL** | **68** | **+20** | **460** | **392** | - |
---
## 🎯 NAČRT ZA DANES (1.1.2026)
| Task | PNG Output | Čas | Status |
|:-----|:----------:|:---:|:------:|
| **Task 1.1: Anomalous Fauna** | +96 | 90 min | ⏳ Pending |
| **Task 1.2: Character Animations** | +120 | 2h | ⏳ Pending |
| **Task 1.3: Biome Packs (Optional)** | +200-300 | 3-4h | ⏳ Optional |
| **Task 1.4: Background Removal** | Processing | 30 min | ⏳ Pending |
| **TOTAL DANES** | **+216 (min)** <br> **+516 (max)** | **3-7h** | 🚀 **Ready!** |
---
## 📊 ASSET COUNT PROJECTION
### Scenario A: Minimum (Core Tasks Only)
| Category | Current | Today | Total After | Progress |
|:---------|--------:|------:|------------:|---------:|
| **Existing Assets** | 752 | - | 752 | - |
| **Anomalous Fauna** | 32 | +96 | 128 | +300% |
| **Character Animations** | 294 | +120 | 414 | +41% |
| **TOTAL** | **752** | **+216** | **968** | **7.2%** |
### Scenario B: Maximum (All Optional Tasks)
| Category | Current | Today | Total After | Progress |
|:---------|--------:|------:|------------:|---------:|
| **Existing Assets** | 752 | - | 752 | - |
| **Anomalous Fauna** | 32 | +96 | 128 | +300% |
| **Character Animations** | 294 | +120 | 414 | +41% |
| **Biome Packs (2-3)** | 0 | +300 | 300 | NEW! |
| **TOTAL** | **752** | **+516** | **1,268** | **9.4%** |
---
## 🏆 MILESTONE TRACKING
| Milestone | PNG Target | Current | Remaining | ETA |
|:----------|:----------:|--------:|----------:|:---:|
| **MVP Demo** | 1,000 | 752 | 248 | 🟢 Today-Tomorrow |
| **Kickstarter** | 2,500 | 752 | 1,748 | 🟡 Week 1-2 |
| **Alpha 1.0** | 5,000 | 752 | 4,248 | 🟡 Month 1 |
| **Alpha 2.0** | 8,000 | 752 | 7,248 | 🔴 Month 2 |
| **Full Game** | 13,500 | 752 | 12,748 | 🔴 Month 3-4 |
---
## 📋 DETAILED BREAKDOWN BY CATEGORY
### 🧑 Characters (Total Target: 1,500)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Kai Animations | 265 | +40 | 305 | 400 | 95 |
| Ana Animations | 15 | +40 | 55 | 400 | 345 |
| Gronk Animations | 14 | +40 | 54 | 400 | 346 |
| NPCs | 48 | - | 48 | 180 | 132 |
| **Subtotal** | **342** | **+120** | **462** | **1,380** | **918** |
### 🦖 Biomes - Anomalous Zones (Target: 1,800)
| Biome | Current | Today | After | Target | % |
|:------|--------:|------:|------:|-------:|--:|
| Dinozavri | 32 | - | 32 | 100 | 32% |
| Mythical Highlands | 0 | +12 | 12 | 100 | 12% |
| Endless Forest | 0 | +12 | 12 | 100 | 12% |
| Loch Ness | 0 | +12 | 12 | 100 | 12% |
| Egyptian Desert | 0 | +12 | 12 | 100 | 12% |
| Amazonas | 0 | +12 | 12 | 100 | 12% |
| Atlantis | 0 | +12 | 12 | 100 | 12% |
| Chernobyl | 0 | +12 | 12 | 100 | 12% |
| Catacombs | 0 | +12 | 12 | 100 | 12% |
| Mexican Cenotes | 0 | *(+100)* | 100 | 100 | 0%→100% |
| Witch Forest | 0 | *(+100)* | 100 | 100 | 0%→100% |
| Auroras | 0 | - | 0 | 100 | 0% |
| **Subtotal** | **32** | **+96 (+200)** | **328** | **1,800** | **18%** |
*Note: (+200) = optional biome packs if doing Task 1.3*
### 🗡️ Combat & Equipment (Target: 2,500)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Weapons | 10 | - | 10 | 150 | 140 |
| Armor/Clothing | 0 | - | 0 | 200 | 200 |
| Tools | 10 | - | 10 | 80 | 70 |
| **Subtotal** | **20** | **0** | **20** | **430** | **410** |
### 🌾 Resources & Items (Target: 3,500)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Food | 10 | - | 10 | 200 | 190 |
| Plants | 71 | - | 71 | 300 | 229 |
| Materials | 0 | - | 0 | 250 | 250 |
| Seeds | 0 | - | 0 | 150 | 150 |
| **Subtotal** | **81** | **0** | **81** | **900** | **819** |
### 🏘️ World & Environment (Target: 4,000)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Buildings | 16 | - | 16 | 500 | 484 |
| Terrain Tiles | 0 | - | 0 | 800 | 800 |
| Props | 0 | - | 0 | 600 | 600 |
| Decorations | 0 | - | 0 | 400 | 400 |
| **Subtotal** | **16** | **0** | **16** | **2,300** | **2,284** |
### 🧟 Enemies (Target: 1,200)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Zombies | 68 | - | 68 | 300 | 232 |
| Mutants | 0 | - | 0 | 150 | 150 |
| Bosses | 0 | - | 0 | 80 | 80 |
| Hybrids | 0 | - | 0 | 100 | 100 |
| **Subtotal** | **68** | **0** | **68** | **630** | **562** |
### 🎨 UI & Effects (Target: 1,000)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| UI Elements | 24 | - | 24 | 400 | 376 |
| VFX/Particles | 0 | - | 0 | 300 | 300 |
| Icons | 0 | - | 0 | 200 | 200 |
| **Subtotal** | **24** | **0** | **24** | **900** | **876** |
### 📦 Misc & Other (Target: 500)
| Asset Type | Current | Today | After | Target | Remaining |
|:-----------|--------:|------:|------:|-------:|----------:|
| Ostalo | 169 | - | 169 | 500 | 331 |
| **Subtotal** | **169** | **0** | **169** | **500** | **331** |
---
## 🎯 GRAND TOTAL SUMMARY
| Metric | Value |
|:-------|------:|
| **Current Assets** | 752 PNG |
| **Generated Today (Min)** | +216 PNG |
| **Generated Today (Max)** | +516 PNG |
| **Total After Today (Min)** | 968 PNG |
| **Total After Today (Max)** | 1,268 PNG |
| **Final Target** | 13,500 PNG |
| **Remaining After Today (Min)** | 12,532 PNG |
| **Remaining After Today (Max)** | 12,232 PNG |
| **Current Progress** | 5.6% |
| **Progress After Today (Min)** | 7.2% |
| **Progress After Today (Max)** | 9.4% |
---
## 📅 PRODUCTION VELOCITY ESTIMATE
**Assuming 200-500 PNG per day**:
- **Week 1**: 752 → 2,252 PNG (16.7%)
- **Week 2**: 2,252 → 3,752 PNG (27.8%)
- **Month 1**: 752 → 6,752 PNG (50%)
- **Month 2**: 6,752 → 13,252 PNG (98.2%)
- **ETA to 13,500**: **~45-60 days** (end of February 2026)
---
## ✅ TODAY'S GOALS
### Minimum Success Criteria:
- [x] Current: 752 PNG
- [ ] After Task 1.1: 848 PNG (+96 fauna)
- [ ] After Task 1.2: 968 PNG (+120 animations)
- [ ] **Target**: **968 PNG = 7.2%**
### Stretch Goals:
- [ ] Complete 1 Biome Pack: +100 PNG → 1,068 PNG (7.9%)
- [ ] Complete 2 Biome Packs: +200 PNG → 1,168 PNG (8.7%)
- [ ] Complete 3 Biome Packs: +300 PNG → 1,268 PNG (9.4%)
- [ ] **Stretch Target**: **1,268 PNG = 9.4%** 🚀
---
## 🎆 NEXT MILESTONES
1. **1,000 PNG** - MVP Demo Ready (Today-Tomorrow)
2. **2,500 PNG** - Kickstarter Launch (Week 2)
3. **5,000 PNG** - Alpha 1.0 (Month 1)
4. **8,000 PNG** - Alpha 2.0 (Month 2)
5. **13,500 PNG** - Full Game Release (Month 2-3)
---
**Status**: 🚀 **PRODUCTION ACTIVE!**
**Created**: 1.1.2026 @ 12:45
**Last Count**: 752 PNG
**Next Update**: After Task 1.1 completion

View File

@@ -0,0 +1,104 @@
# 🎯 CHARACTER ANIMATION GENERATION - FINAL PLAN
**Datum**: 1.1.2026
**Status**: API Configured, Billing Enabled ✅
---
## ❌ **PROBLEM IDENTIFICIRAN:**
Google Gemini API **NE PODPIRA IMAGE GENERATION** preko REST API-ja!
- Gemini 2.0 Flash = **text generation model**
- Imagen 3 = **ni dostopen preko Gemini API**
- Image generation = **samo v AI Studio UI**
---
## ✅ **3 DELUJOČE ALTERNATIVE:**
### **Option 1: Google AI Studio Manual (DANES, ZASTONJ!)**
1. Pojdi na: https://aistudio.google.com
2. Nov chat → Gemini Advanced (ker imaš naročnino!)
3. Prompt: "Generate character Kai - green pink dreadlocks, age 17, walking animation frame 1, front view, bold outlines, transparent background"
4. **Generate Image** button
5. Download sliko
6. Repeat za vse frame (58 frames = 1 ura ročnega dela)
**Pros**: Zastonj, dela takoj
**Cons**: Ročno (58× ponavljanje)
---
### **Option 2: Bing Image Creator (DANES, UNLIMITED!)**
1. https://www.bing.com/create
2. Sign in z Microsoft
3. Paste prompt
4. Generira 4 slike naenkrat!
5. Download batch
6. **UNLIMITED** - brez limitov!
**Pros**: Unlimited, hitro (4 slike/min)
**Cons**: Microsoft račun potreben
---
### **Option 3: Leonardo.AI (DANES, 150 slik)**
1. https://leonardo.ai
2. Sign up zastonj
3. 150 credits/dan
4. Batch generation možen
5. API dostop
**Pros**: API iz Pythona, batch download
**Cons**: 150/dan limit (need 3 dni za vse)
---
## 🚀 **PRIPOROČILO:**
### **ZA DANES (Option 2 - Bing):**
1. **Setup** (2 min):
- Pojdi na https://www.bing.com/create
- Sign in
2. **Batch generacija** (2-3h):
- Kopiraj prompte iz `CHARACTER_PRODUCTION_PLAN.md`
- Paste v Bing
- Download vse 4 slike
- Repeat 15× (58 frames ÷ 4 = 15 batch-ov)
3. **Organize** (30 min):
- Rename files (kai_walk_frame1.png, etc.)
- Move v `assets/slike/kai/`, `ana/`, `gronk/`
- Background removal batch
**Total čas**: ~3-4 ure
**Cost**: ZASTONJ
**Result**: Vse 58 essential frames ✅
---
## 💡 **ALI PA:**
**Za JUTRI** (Google AI Studio):
- Pojdi na https://console.cloud.google.com/vertex-ai
- Enable **Vertex AI Imagen API**
- Potem ima pravilni API endpoint za image generation
- Script bo delal!
---
## 📋 **NEXT STEPS:**
**Katera opcija izbirateš?**
1. **Bing Image Creator** → Dam ti prompte, ti generiraš ročno (3h)
2. **Google AI Studio UI** → Dam ti prompte, generiraš v UI (1h)
3. **Počakaj jutri** → Enableam Vertex AI, script avtomatsko (setup 10min potem 3h generacija)
**Povej mi!** 🎯

View File

@@ -0,0 +1,270 @@
# 👥 GLAVNI KARAKTERJI - PRODUCTION PLAN
**Datum**: 1.1.2026
**Status**: Planning Phase
**Cilj**: Definirati vse potrebne assete za Kai, Ana, Gronk
---
## 📊 TRENUTNO STANJE
| Karakter | Trenutno | Master Ref | Animacije | Status |
|:---------|:--------:|:----------:|:---------:|:------:|
| **Kai** | 1 PNG | ✅ | ❌ | 🔴 NEED WORK |
| **Ana** | 0 PNG | ✅ (konsistentno) | ❌ | 🔴 NEED WORK |
| **Gronk** | 1 PNG | ✅ | ❌ | 🔴 NEED WORK |
**Locked References** (v `assets/slike/konsistentno/`):
-`kai_master_styleA_reference.png`
-`kai_master_styleB_reference.png`
-`ana_master_styleA_reference.png`
-`ana_master_styleB_reference.png`
-`gronk_master_styleA_reference.png`
-`gronk_master_styleB_reference.png`
---
## 🎮 KAJ POTREBUJEMO ZA VSAK KARAKTER?
### 🧑 **1. KAI (Protagonist - Zombie Whisperer)**
#### A. Osnovne Animacije (CRITICAL)
| Animation | Frames | Directions | Total PNG | Prioriteta |
|:----------|:------:|:----------:|:---------:|:----------:|
| **Walk Cycle** | 4 | 8 (N,NE,E,SE,S,SW,W,NW) | 32 | 🔥 HIGH |
| **Idle** | 4 | 2 (side, front) | 8 | 🔥 HIGH |
| **Run** | 4 | 8 | 32 | 🔶 MEDIUM |
| **SUBTOTAL** | - | - | **72** | - |
#### B. Action Animacije (GAMEPLAY)
| Action | Frames | Directions | Total PNG | Prioriteta |
|:-------|:------:|:----------:|:---------:|:----------:|
| **Attack (Sword/Melee)** | 4 | 4 (N,E,S,W) | 16 | 🔥 HIGH |
| **Dig (Shovel)** | 4 | 4 | 16 | 🔥 HIGH |
| **Plant (Seeds)** | 3 | 2 | 6 | 🔶 MEDIUM |
| **Harvest** | 3 | 2 | 6 | 🔶 MEDIUM |
| **Drink/Eat** | 3 | 1 | 3 | 🔷 LOW |
| **Use Item** | 3 | 2 | 6 | 🔷 LOW |
| **SUBTOTAL** | - | - | **53** | - |
#### C. Emotional/Story Animacije (CUTSCENE)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Sad/Crying** | 4 | 4 | 🔷 LOW |
| **Happy/Celebrate** | 4 | 4 | 🔷 LOW |
| **Thinking** | 3 | 3 | 🔷 LOW |
| **Shocked** | 2 | 2 | 🔷 LOW |
| **SUBTOTAL** | - | **13** | - |
#### D. Combat Special (ALPHA 2.0)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Zombie Command** (gesture) | 4 | 4 | 🔵 LATER |
| **Telepathy Effect** | 6 | 6 | 🔵 LATER |
| **Hurt/Damaged** | 3 | 3 | 🔶 MEDIUM |
| **Death** | 5 | 5 | 🔷 LOW |
| **SUBTOTAL** | - | **18** | - |
### **KAI TOTAL: 156 PNG**
---
### 💜 **2. ANA (Twin Sister - Scientist)**
#### A. Osnovne Animacije (CRITICAL)
| Animation | Frames | Directions | Total PNG | Prioriteta |
|:----------|:------:|:----------:|:---------:|:----------:|
| **Walk Cycle** | 4 | 8 | 32 | 🔥 HIGH |
| **Idle** | 4 | 2 | 8 | 🔥 HIGH |
| **Run** | 4 | 8 | 32 | 🔶 MEDIUM |
| **SUBTOTAL** | - | - | **72** | - |
#### B. Action Animacije (SCIENTIST THEME)
| Action | Frames | Directions | Total PNG | Prioriteta |
|:-------|:------:|:----------:|:---------:|:----------:|
| **Research** (notebook) | 4 | 2 | 8 | 🔥 HIGH |
| **Heal** (apply bandage) | 4 | 2 | 8 | 🔥 HIGH |
| **Examine** (magnifying glass) | 3 | 2 | 6 | 🔶 MEDIUM |
| **Mix Potion** | 4 | 1 | 4 | 🔶 MEDIUM |
| **Collect Sample** | 3 | 2 | 6 | 🔷 LOW |
| **SUBTOTAL** | - | - | **32** | - |
#### C. Emotional/Story (TWIN BOND THEME)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Worried** | 4 | 4 | 🔥 HIGH (story) |
| **Relief** | 4 | 4 | 🔥 HIGH (story) |
| **Twin Bond Glow** | 6 | 6 | 🔶 MEDIUM |
| **Flashback Pose** | 3 | 3 | 🔷 LOW |
| **SUBTOTAL** | - | **17** | - |
#### D. Combat/Support (SUPPORT ROLE)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Defend** (staff block) | 4 | 4 | 🔶 MEDIUM |
| **Cure Cast** | 5 | 5 | 🔶 MEDIUM |
| **Hurt** | 3 | 3 | 🔷 LOW |
| **Death** | 5 | 5 | 🔷 LOW |
| **SUBTOTAL** | - | **17** | - |
### **ANA TOTAL: 138 PNG**
---
### 💚 **3. GRONK (Zen Troll - Comic Relief)**
#### A. Osnovne Animacije (CRITICAL)
| Animation | Frames | Directions | Total PNG | Prioriteta |
|:----------|:------:|:----------:|:---------:|:----------:|
| **Walk Cycle** (heavy) | 4 | 8 | 32 | 🔥 HIGH |
| **Idle** (chill stance) | 4 | 2 | 8 | 🔥 HIGH |
| **Run** (slow lumbering) | 4 | 8 | 32 | 🔶 MEDIUM |
| **SUBTOTAL** | - | - | **72** | - |
#### B. Action Animacije (TROLL THEME)
| Action | Frames | Directions | Total PNG | Prioriteta |
|:-------|:------:|:----------:|:---------:|:----------:|
| **Vape** 💨 (signature!) | 6 | 2 | 12 | 🔥 HIGH |
| **Smash** (club attack) | 5 | 4 | 20 | 🔥 HIGH |
| **Lift Heavy** | 4 | 2 | 8 | 🔶 MEDIUM |
| **Meditate** (zen pose) | 4 | 1 | 4 | 🔷 LOW |
| **SUBTOTAL** | - | - | **44** | - |
#### C. Emotional (COMIC RELIEF)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Laugh** | 4 | 4 | 🔶 MEDIUM |
| **Confused** | 3 | 3 | 🔷 LOW |
| **Chill/Relaxed** | 3 | 3 | 🔷 LOW |
| **SUBTOTAL** | - | **10** | - |
#### D. Combat (TANK ROLE)
| Animation | Frames | Total PNG | Prioriteta |
|:----------|:------:|:---------:|:----------:|
| **Block** (shield up) | 3 | 3 | 🔶 MEDIUM |
| **Taunt** | 4 | 4 | 🔷 LOW |
| **Hurt** | 3 | 3 | 🔶 MEDIUM |
| **Death** | 5 | 5 | 🔷 LOW |
| **SUBTOTAL** | - | **15** | - |
### **GRONK TOTAL: 141 PNG**
---
## 📊 GRAND TOTAL SUMMARY
| Character | Walk/Run | Actions | Emotions | Combat | TOTAL |
|:----------|:--------:|:-------:|:--------:|:------:|------:|
| **Kai** | 72 | 53 | 13 | 18 | **156** |
| **Ana** | 72 | 32 | 17 | 17 | **138** |
| **Gronk** | 72 | 44 | 10 | 15 | **141** |
| **GRAND TOTAL** | **216** | **129** | **40** | **50** | **435** |
---
## 🎯 PHASED PRODUCTION STRATEGY
### **PHASE 1: CORE GAMEPLAY** (Priority 🔥 HIGH)
**Cilj**: Playable characters z basic animations
| Character | Animations | PNG Count | Čas Est. |
|:----------|:-----------|:---------:|:--------:|
| Kai | Walk (32) + Idle (8) + Attack (16) + Dig (16) | 72 | 1.5h |
| Ana | Walk (32) + Idle (8) + Research (8) + Heal (8) | 56 | 1h |
| Gronk | Walk (32) + Idle (8) + Vape (12) + Smash (20) | 72 | 1.5h |
| **PHASE 1 TOTAL** | - | **200 PNG** | **~4h** |
---
### **PHASE 2: EXPANDED GAMEPLAY** (Priority 🔶 MEDIUM)
**Cilj**: More actions + story emotions
| Character | Animations | PNG Count | Čas Est. |
|:----------|:-----------|:---------:|:--------:|
| Kai | Run (32) + Plant (6) + Harvest (6) + Hurt (3) | 47 | 1h |
| Ana | Run (32) + Examine (6) + Mix (4) + Worried (4) | 46 | 1h |
| Gronk | Run (32) + Lift (8) + Laugh (4) + Hurt (3) | 47 | 1h |
| **PHASE 2 TOTAL** | - | **140 PNG** | **~3h** |
---
### **PHASE 3: POLISH & CUTSCENES** (Priority 🔷 LOW)
**Cilj**: Full emotional range + story sequences
| Character | Animations | PNG Count | Čas Est. |
|:----------|:-----------|:---------:|:--------:|
| Kai | Emotions (13) + Use Item (6) + Eat (3) + Death (5) | 27 | 45 min |
| Ana | Twin Bond (6) + Flashback (3) + Death (5) + Relief (4) | 18 | 30 min |
| Gronk | Meditate (4) + Confused (3) + Taunt (4) + Death (5) | 16 | 30 min |
| **PHASE 3 TOTAL** | - | **61 PNG** | **~2h** |
---
### **PHASE 4: ADVANCED SYSTEMS** (Priority 🔵 ALPHA 2.0)
**Cilj**: Special abilities + effects
| Character | Animations | PNG Count | Čas Est. |
|:----------|:-----------|:---------:|:--------:|
| Kai | Zombie Command (4) + Telepathy (6) | 10 | 20 min |
| Ana | Collect Sample (6) + Cure Cast (5) | 11 | 20 min |
| Gronk | Block (3) + Chill (3) | 6 | 15 min |
| **PHASE 4 TOTAL** | - | **27 PNG** | **~1h** |
---
## ✅ PRODUCTION TIMELINE ESTIMATE
| Phase | PNG Output | Čas | Prioriteta | Kdaj? |
|:------|:----------:|:---:|:----------:|:-----:|
| **Phase 1: Core** | 200 | 4h | 🔥 CRITICAL | **Danes!** |
| **Phase 2: Expanded** | 140 | 3h | 🔶 HIGH | Jutri |
| **Phase 3: Polish** | 61 | 2h | 🔷 MEDIUM | Dan 3 |
| **Phase 4: Advanced** | 27 | 1h | 🔵 LOW | Alpha 2.0 |
| **TOTAL** | **428** | **10h** | - | Week 1 |
---
## 🎨 ART STYLE REQUIREMENTS
### Vsak karakter rabi 2 verzije:
- **Style A** (Cartoon): Bright colors, bold outlines
- **Style B** (Noir): Dark, gritty, high contrast
**Total PNG × 2 = 856 PNG** (if doing both styles)
---
## 📝 GENERATION STRATEGY
### Option A: Batch Generation (Recommended)
1. Generate ALL Phase 1 animations for Kai (72 PNG) - 1.5h
2. Generate ALL Phase 1 animations for Ana (56 PNG) - 1h
3. Generate ALL Phase 1 animations for Gronk (72 PNG) - 1.5h
4. Background removal batch - 30 min
5. **TOTAL TODAY: 200 PNG in 4.5h**
### Option B: Character-by-Character
1. Kai complete (156 PNG) - 3h
2. Ana complete (138 PNG) - 3h
3. Gronk complete (141 PNG) - 3h
4. **TOTAL: 435 PNG in 9h** (full day)
---
## 🚀 RECOMMENDED PLAN FOR TODAY
**Session 1 (Morning - 2h):**
- [ ] Generate Kai Phase 1 (72 PNG)
- [ ] Background removal
**Session 2 (Afternoon - 2h):**
- [ ] Generate Ana Phase 1 (56 PNG)
- [ ] Generate Gronk Phase 1 (72 PNG)
**RESULT**: ✅ **200 PNG - All 3 characters playable!**
---
**Created**: 1.1.2026 @ 12:51
**Status**: 📋 **PLAN READY - AWAITING EXECUTION**
**Next Step**: Start Phase 1 generation OR adjust plan based on feedback

86
COMFYUI_SETUP_TODAY.md Normal file
View File

@@ -0,0 +1,86 @@
# 🎯 COMFYUI SETUP - DANES!
**Datum**: 1.1.2026
**Status**: ComfyUI app found ✅
**Cilj**: Generate slike kot včeraj!
---
## ✅ **KAJ SEM NAŠEL:**
Včeraj si uporabljal **ComfyUI.app**!
Scripts ki so delali:
- `test_hybrid_comfyui.py`
- `generate_assets_local.py`
- `generate_v63_stardew.py`
Vsi kličejo:
- `http://127.0.0.1:8188` (ComfyUI server)
---
## 🚀 **KAJ MORAŠ NAREDITI (3 KORAKI):**
### **KORAK 1: Zaženi ComfyUI app**
**Ročno odpri:**
1. Pojdi v Finder
2. Applications folder
3. Dvojni klik na **ComfyUI.app**
4. Počakaj da se zažene (1-2min)
5. Odpre se browser window na `http://127.0.0.1:8188`
**ALI iz terminala:**
```bash
open /Applications/ComfyUI.app
```
---
### **KORAK 2: Preveri da teče**
Ko se ComfyUI odpre v browser-ju, v terminalu testiraj:
```bash
curl -s http://127.0.0.1:8188/system_stats
```
**Če dela → vidiš JSON z "comfyui_version"**
**Če NE dela → počakaj še malo (app se še zaganja)**
---
### **KORAK 3: Poženi generation script**
Ko ComfyUI teče, poženi:
```bash
cd /Users/davidkotnik/repos/novafarma
python3 scripts/test_hybrid_comfyui.py
```
**To bo generiralo test slike!**
---
## 📝 **POTEM:**
Ko test dela, lahko poganjamo **full character generation** script ki uporablja ComfyUI!
Naredim ti script ki generira vse 58 essential frames preko ComfyUI (kot včeraj).
---
## ⚡ **QUICKSTART:**
1. **Odpri ComfyUI.app** (dvojni klik v Applications)
2. **Počakaj** da se zažene (1-2 min)
3. **Povej mi** ko se odpre browser window
4. **Poženem** generation script!
---
**STATUS**: Ready! ComfyUI app je instaliran, samo zagnati ga moraš! 🚀
**Pošlji mi screenshot ko se ComfyUI odpre!**

587
TASKS_01_01_2026.md Normal file
View File

@@ -0,0 +1,587 @@
# 🎯 TASKS - 1.1.2026 (SREČNO NOVO LETO!)
**Datum**: 1.1.2026
**Status**: API Kvota RESET @ 01:00 CET ✅
**Cilj**: Masovna produkcija asset-ov + System Integration
---
## 🚀 PRIORITETA 1: ASSET GENERATION (GLAVNA PRIORITETA!)
### ✅ Status Check
- [x] Dino Valley fauna (32/32 PNG) - **COMPLETE!**
- [x] API kvota reset - **READY!**
- [x] Scripts pripravļjeni - **READY!**
### 🎨 Task 1.1: Generate Anomalous Zone Fauna (96 PNG)
**Čas**: 90 min
**Prioriteta**: 🔥 CRITICAL
**Script**: `scripts/generate_anomalous_fauna.py`
**8 Zon za generirati**:
1. Mythical Highlands (12 PNG) - unicorns, dragons, griffins
2. Endless Forest (12 PNG) - bigfoot, wendigo, forest spirits
3. Loch Ness (12 PNG) - Nessie, leprechauns, kelpies
4. Egyptian Desert (12 PNG) - mummies, scarabs, anubis
5. Amazonas (12 PNG) - jaguars, anacondas, piranhas
6. Atlantis (12 PNG) - mermaids, sea serpents, dolphins
7. Chernobyl (12 PNG) - radioactive mutants, troll king
8. Catacombs (12 PNG) - skeletons, ghosts, lich
**Action**:
```bash
cd /Users/davidkotnik/repos/novafarma
python scripts/generate_anomalous_fauna.py
```
**Checklist**:
- [ ] Poženi script
- [ ] Preveri da vse slike generira (96 PNG)
- [ ] Run background removal
- [ ] Preveri kvaliteto
- [ ] Commit to git
---
### 👤 Task 1.2: Generate Character Animations (120 PNG)
**Čas**: 2h
**Prioriteta**: 🔥 CRITICAL
**Script**: `scripts/generate_character_animations.py`
**Characters**:
- Kai (40 PNG) - walk cycle 8-way, idle, attack, dig, plant
- Ana (40 PNG) - walk cycle 8-way, idle, research, heal
- Gronk (40 PNG) - walk cycle 8-way, idle, vape, smash
**Action**:
```bash
cd /Users/davidkotnik/repos/novafarma
python scripts/generate_character_animations.py
```
**Checklist**:
- [ ] Poženi script
- [ ] Preveri animacije (smooth transitions)
- [ ] Background removal batch
- [ ] Organize v `assets/slike/kai/`, `ana/`, `gronk/`
- [ ] Commit to git
---
### 🌍 Task 1.3: Complete 2-3 Biome Asset Packs (Optional)
**Čas**: 3-4h
**Prioriteta**: 🔶 HIGH
**Script**: Adapt existing scripts
**Priority Biomes**:
1. **Mexican Cenotes** - axolotls, cave crystals, mayan gear
2. **Witch Forest** - witches, potions, dark magic items
3. **Mythical Highlands** - expand from fauna task
**Per Biome** (~100 PNG each):
- Fauna (12) - from Task 1.1
- Clothing (15) - theme-specific outfits
- Weapons (10) - unique to biome
- Food (10) - regional cuisine
- Materials (15) - crafting resources
- Terrain (10) - ground tiles
- Vegetation (15) - plants/trees
- Props (10) - decorations
- Buildings (3) - structures
**Checklist**:
- [ ] Choose 2-3 biomes
- [ ] Create/adapt generation script
- [ ] Generate all assets
- [ ] Background removal
- [ ] Organize v `assets/slike/[biome_name]/`
- [ ] Commit to git
---
### 🎯 Task 1.4: Background Removal Batch Processing
**Čas**: 30 min
**Prioriteta**: 🔶 HIGH
**Script**: `scripts/remove_bg_advanced.py`
**Action**:
```bash
cd /Users/davidkotnik/repos/novafarma
python scripts/remove_bg_advanced.py
```
**Checklist**:
- [ ] Run na vse novo generirane PNG
- [ ] Preveri alpha channels
- [ ] Resize na game-ready dimensions
- [ ] Create previews
---
## 🔧 PRIORITETA 2: SYSTEM INTEGRATION
### 🧪 Task 2.1: Basic Smoke Test
**Čas**: 10 min
**Prioriteta**: 🔥 CRITICAL (FIRST!)
**File**: Trenutna igra
**Test Checklist**:
- [ ] Odpri igro (npm start)
- [ ] Preveri Console za errors
- [ ] Player spawna?
- [ ] WASD movement dela?
- [ ] Inventory (I key) dela?
- [ ] Crafting (C key) dela?
- [ ] Save system (F5) dela?
**Če vse dela → nadaljuj Task 2.2**
**Če NE dela → FIX najprej!**
---
### ⚙️ Task 2.2: Initialize New Systems in GameScene
**Čas**: 1h
**Prioriteta**: 🔥 CRITICAL
**File**: `src/scenes/GameScene.js`
**Action**: Dodaj v `create()` function (po line ~800):
```javascript
// ========================================================
// 🆕 NEW SYSTEMS (P16-P30) - 1.1.2026
// ========================================================
console.log('🆕 Initializing New Systems (P16-P30)...');
// P16: Mining System
console.log('⛏️ Initializing Mining System...');
this.miningSystem = new MiningSystem(this);
// P17: Character Customization
console.log('👤 Initializing Character Customization...');
this.characterCustomization = new CharacterCustomizationSystem(this);
// P19: Town Restoration
console.log('🏘️ Initializing Town Restoration...');
this.townRestoration = new TownRestorationSystem(this);
// P20: Portal Repair
console.log('🌀 Initializing Portal Repair...');
this.portalRepair = new PortalRepairSystem(this);
// P22: Smart Zombies
console.log('🧠 Initializing Smart Zombies...');
this.smartZombies = new SmartZombieSystem(this);
// P23: Tool System
console.log('🔧 Initializing Tool System...');
this.toolSystem = new ToolSystem(this);
// P25: Ana's Clues
console.log('💜 Initializing Ana Clues...');
this.anaClues = new AnaClueSystem(this);
// P26: Pyramids
console.log('🏜️ Initializing Pyramid System...');
this.pyramids = new PyramidSystem(this);
// P27: Slimes & Dogs
console.log('🟢🐶 Initializing Slimes & Dogs...');
this.slimesDogs = new SlimesDogsSystem(this);
// P28: Animals & Seeds
console.log('🐄🌱 Initializing Animals & Seeds...');
this.animalsSeeds = new AnimalsSeedsSystem(this);
// P29: Automation
console.log('⚙️ Initializing Automation...');
this.automation = new AutomationSystem(this);
// P30: Inventory Expanded
console.log('🎒 Initializing Inventory Expansion...');
this.inventoryExpanded = new InventorySystemExpanded(this, this.inventorySystem);
console.log('✅ All New Systems Initialized!');
```
**Checklist**:
- [ ] Odpri `src/scenes/GameScene.js`
- [ ] Najdi `create()` function
- [ ] Dodaj kodo
- [ ] Shrani
- [ ] Test reload (preveri Console za "✅ All New Systems Initialized!")
---
### 🔄 Task 2.3: Add System Updates to update() Loop
**Čas**: 30 min
**Prioriteta**: 🔥 CRITICAL
**File**: `src/scenes/GameScene.js`
**Action**: Dodaj v `update(time, delta)` function:
```javascript
update(time, delta) {
// ... existing update code ...
// 🆕 NEW: Daily automation
if (this.automation) {
const currentDay = Math.floor(time / 86400000); // ms to days
if (currentDay !== this.lastDay) {
this.automation.runDailyAutomation();
this.lastDay = currentDay;
}
}
// 🆕 NEW: Animal updates
if (this.animalsSeeds) {
this.animalsSeeds.updateLivestock();
}
// 🆕 NEW: Smart zombie updates
if (this.smartZombies) {
this.smartZombies.updateZombies(delta);
}
// 🆕 NEW: Town construction
if (this.townRestoration) {
this.townRestoration.updateConstruction(delta);
}
// 🆕 NEW: Portal construction
if (this.portalRepair) {
this.portalRepair.updateConstruction(delta);
}
}
```
**Checklist**:
- [ ] Najdi `update(time, delta)` function
- [ ] Dodaj kodo
- [ ] Shrani
- [ ] Test: preveri da sistemi tečejo (Console logs)
---
### 🔗 Task 2.4: Connect System Communications
**Čas**: 1h
**Prioriteta**: 🔶 HIGH
**File**: `src/scenes/GameScene.js`
**Action**: Dodaj v `create()` function (PO inicializaciji sistemov):
```javascript
// ========================================================
// 🔗 SYSTEM CONNECTIONS
// ========================================================
console.log('🔗 Connecting Systems...');
// A. SmartZombies ↔ ZombieSystem
if (this.smartZombies && this.zombieSystem) {
this.smartZombies.baseZombieSystem = this.zombieSystem;
}
// B. ToolSystem ↔ InventorySystem
if (this.toolSystem && this.inventorySystem) {
this.toolSystem.inventorySystem = this.inventorySystem;
}
// C. AnaClues ↔ TwinBondSystem
if (this.anaClues && this.twinBondSystem) {
this.anaClues.onClueFound = (clueId) => {
this.twinBondSystem.triggerMemory(clueId);
};
}
// D. Automation ↔ Multiple Systems
if (this.automation) {
this.automation.farmingSystem = this.farmingSystem;
this.automation.smartZombies = this.smartZombies;
this.automation.inventoryExpanded = this.inventoryExpanded;
}
console.log('✅ Systems Connected!');
```
**Checklist**:
- [ ] Dodaj kodo
- [ ] Shrani
- [ ] Test: preveri da sistemi komunicirajo
---
### 🧪 Task 2.5: Full Integration Test
**Čas**: 30 min
**Prioriteta**: 🔶 HIGH
**Test Checklist**:
- [ ] Igra se zažene brez napak
- [ ] Vsi 46 sistemov inicializirani (Console check)
- [ ] Player movement dela
- [ ] Inventory dela
- [ ] Crafting dela
- [ ] Mining works (zberi resource)
- [ ] Tool durability dela
- [ ] Save/Load dela
- [ ] No memory leaks (check after 5 min gameplay)
- [ ] 60 FPS maintained
---
## 🎨 PRIORITETA 3: UI CREATION (OPTIONAL)
### 👤 Task 3.1: Character Creation Scene (Critical)
**Čas**: 2h
**Prioriteta**: 🔶 HIGH
**File**: `src/scenes/CharacterCreationScene.js` (CREATE NEW)
**Features Needed**:
- Gender selection (Kai/Ana radio buttons)
- Hair color picker (RGB sliders)
- Body customization (sliders)
- Outfit selection (grid of icons)
- Preview window (live update)
- "Start Game" button
**Checklist**:
- [ ] Create file
- [ ] Implement UI layout
- [ ] Wire up to CharacterCustomizationSystem
- [ ] Add to index.html
- [ ] Test flow (creation → game start)
---
### 🧟 Task 3.2: Smart Zombie Command UI
**Čas**: 1h
**Prioriteta**: 🔷 MEDIUM
**File**: `src/ui/SmartZombieUI.js` (CREATE NEW)
**Features Needed**:
- Zombie list (scrollable)
- Command buttons: Stop, Help, Attack, Home
- Follower count display
- XP/Level display per zombie
**Checklist**:
- [ ] Create file
- [ ] Implement UI
- [ ] Wire up to SmartZombieSystem
- [ ] Add to index.html
- [ ] Test commands
---
### 💜 Task 3.3: Ana's Clue Collection UI
**Čas**: 1h
**Prioriteta**: 🔷 MEDIUM
**File**: `src/ui/AnaClueUI.js` (CREATE NEW)
**Features Needed**:
- Progress tracker (15/12/23 clues)
- Gallery view (grid of clues)
- Story milestone indicators
- Clue descriptions on hover/click
**Checklist**:
- [ ] Create file
- [ ] Implement gallery layout
- [ ] Wire up to AnaClueSystem
- [ ] Add to index.html
- [ ] Test clue discovery flow
---
### 🎒 Task 3.4: Inventory Upgrade UI
**Čas**: 45 min
**Prioriteta**: 🔷 MEDIUM
**File**: `src/ui/InventoryUpgradeUI.js` (CREATE NEW)
**Features Needed**:
- Tier upgrade menu (Tier 1 → Tier 5)
- Tool Belt unlock button
- Dog Backpack unlock button
- Quick Sort/Stack/Deposit buttons
**Checklist**:
- [ ] Create file
- [ ] Implement upgrade interface
- [ ] Wire up to InventorySystemExpanded
- [ ] Add to index.html
- [ ] Test upgrades
---
## 🗺️ PRIORITETA 4: TILED MAPS (OPTIONAL)
### 📥 Task 4.1: Import Tilesets to Tiled
**Čas**: 15 min
**Prioriteta**: 🔷 MEDIUM
**Action**:
1. Odpri Tiled Map Editor
2. Map → Add External Tileset
3. Browse → `assets/tilesets/*.tsx`
4. Import vseh 61 TSX files
**Checklist**:
- [ ] Tiled installed
- [ ] Import all TSX
- [ ] Preview tilesets (check visibility)
---
### 🗺️ Task 4.2: Create Starter Map (16x16)
**Čas**: 30 min
**Prioriteta**: 🔷 MEDIUM
**Action**:
1. New Map → 16x16 tiles, 32x32 tile size
2. Add layers:
- Ground (base terrain)
- Decoration (trees, rocks)
- Collision (invisible)
- Objects (player spawn point)
3. Paint basic starter area
4. Add player spawn object (x:8, y:8)
5. Save as `starter_farm_16x16.tmx`
**Checklist**:
- [ ] Create map
- [ ] Add layers
- [ ] Paint terrain
- [ ] Add spawn point
- [ ] Save TMX
---
### 📤 Task 4.3: Export Map to JSON
**Čas**: 5 min
**Prioriteta**: 🔷 MEDIUM
**Action**:
1. File → Export As → JSON
2. Save v `assets/maps/starter_farm_16x16.json`
3. Test load v igri (TiledTestScene.js)
**Checklist**:
- [ ] Export to JSON
- [ ] Preveri JSON syntax
- [ ] Test load v igri
---
## 🐛 PRIORITETA 5: BUG REVIEW (OPTIONAL)
### 🔍 Task 5.1: Code Audit
**Čas**: 1h
**Prioriteta**: 🔵 LOW
**Action**: Review kode za:
- Console errors
- Performance bottlenecks
- Memory leaks
- 303 TODO comments (iz bug audit-a)
**Checklist**:
- [ ] Run game for 10 min
- [ ] Monitor Console
- [ ] Monitor Performance (F3)
- [ ] List critical bugs
- [ ] Document v `BUG_REPORT_01_01_2026.md`
---
### 🔧 Task 5.2: Fix Critical Bugs
**Čas**: 2-4h
**Prioriteta**: 🔵 LOW (only if found)
**Action**: Fix top 3-5 critical bugs found in Task 5.1
**Checklist**:
- [ ] Identify critical bugs
- [ ] Fix them
- [ ] Test fixes
- [ ] Commit
---
## 📊 SESSION TRACKING
### Čas Potreben (Estimate):
- **Asset Generation**: 3-6h
- **System Integration**: 3-4h
- **UI Creation**: 4-6h (optional)
- **Tiled Maps**: 1h (optional)
- **Bug Review**: 2-4h (optional)
**TOTAL**: 6-10h (core) | 13-20h (with optional)
---
## ✅ COMPLETION CHECKLIST
### End of Day Goals:
- [ ] **Asset Count**: +200-400 PNG (min)
- [ ] **Systems**: All 46 initialized and connected
- [ ] **Game Status**: Fully playable with new systems
- [ ] **UI**: At least Character Creation working
- [ ] **Maps**: Starter map created (optional)
- [ ] **Bugs**: No critical errors
---
## 🎯 RECOMMENDED WORKFLOW
### **Session 1 (2h): Morning Kickoff**
1. ✅ Task 2.1: Smoke Test (10 min)
2. 🎨 Task 1.1: Generate Fauna (90 min)
3. 🔧 Task 1.4: Background Removal (30 min)
### **Session 2 (3h): System Integration**
1. ⚙️ Task 2.2: Initialize Systems (1h)
2. 🔄 Task 2.3: Add Updates (30 min)
3. 🔗 Task 2.4: Connect Systems (1h)
4. 🧪 Task 2.5: Integration Test (30 min)
### **Session 3 (2h): Character Animations**
1. 👤 Task 1.2: Generate Animations (2h)
### **Session 4 (2h): UI or Biomes**
**Option A**: UI Focus
- 👤 Task 3.1: Character Creation (2h)
**Option B**: Asset Focus
- 🌍 Task 1.3: Complete 1 Biome (2h)
### **Session 5 (1-2h): Polish**
- Additional UI screens OR
- Map creation OR
- Bug fixes
---
## 📝 NOTES
**Asset Priority**:
1. Character animations (CORE gameplay)
2. Anomalous fauna (variety)
3. Complete biomes (showcase)
**Code Priority**:
1. Smoke test (check current state)
2. System integration (get 46 systems working)
3. UI (playability)
**Don't Forget**:
- ✅ Commit often (after each major task)
- ✅ Test frequently
- ✅ Take breaks (every 2h)
- ✅ API rate limiting (15s delay between calls)
---
**Created**: 1.1.2026 12:42
**Status**: 🚀 READY TO EXECUTE!
**Next Step**: Start with Task 2.1 (Smoke Test) OR Task 1.1 (Fauna Generation)
🎆 **SREČNO NOVO LETO! LET'S BUILD THIS GAME!** 🎆

View File

@@ -0,0 +1,90 @@
# DolinaSmrti: Krvava Žetev (Bloody Harvest) - Complete Narrative Overview
## 📖 The Core Premise
**DolinaSmrti** is a 2.5D Isometric Survival RPG set in a stylized, hand-drawn post-apocalyptic Slovenia (2085). It tells the emotional story of two teenage twins, **Kai** and **Ana Marković**, separated by a tragic event, and their journey to find each other in a world overrun by the undead.
---
## 🎭 The Characters
### 1. Kai Marković (The Protagonist)
- **Role**: The Survivor / "The Zombie Whisperer".
- **Visuals**: Green & Pink dreadlocks, tactical gear.
- **Ability**: Infected with a rare strain (Alpha Hybrid) that didn't turn him into a zombie but gave him the power to **telepathically control them**. He uses zombies as workforce for his farm.
- **Motivation**: To find his twin sister, Ana, at any cost.
### 2. Ana Marković (The Lost Twin)
- **Role**: The Key / The Biologist.
- **Visuals**: Matches Kai's style (Pink dreads), often seen in visions/flashbacks.
- **Status**: Kidnapped. She holds the secret to the true cure within her blood/research.
- **Location**: Unknown (initially), later revealed to be held in a high-security Bio-Lab.
### 3. Gronk (The Companion)
- **Role**: The Heart / Comic Relief.
- **Species**: Peaceful Troll.
- **Visuals**: Large green troll, pink hair, piercings, vapes regularly.
- **Backstory**: Cousin to the main antagonist (The Giant Troll King). Rejected his violent family to live a "Zen" life. Helps Kai manage the farm and provides moral support.
### 4. Dr. Viktor Krnić (The Antagonist)
- **Role**: The Mad Scientist.
- **Goal**: To weaponize the virus and create a "Super Race" using Ana's unique biology.
- **Base**: Chernobyl Reactor Core (The ultimate destination).
### 5. The Giant Troll King (The Enforcer)
- **Role**: Gronk's evil cousin.
- **Deed**: The one who physically snatched Ana during the outbreak.
---
## 📜 The Story Arc
### 🎬 Prologue: The Separation (2084)
In the chaos of the initial outbreak at **Nova Lab**, Kai and Ana's parents sacrifice themselves to save their children.
- **The Incident**: A massive breach occurs.
- **The Event**: Kai is bitten/infected but transforms into a Hybrid instead of turning.
- **The Tragedy**: In the confusion, The Giant Troll King smashes through the defenses and grabs Ana, taking her away into the darkness. Kai passes out from the infection.
### 🌾 Act 1: The Awakening & The Farm (2085)
**Location**: The Valley of Death (Dolina Smrti).
- Kai wakes up a year later, alone.
- He realizes his power: The zombies don't attack him; they listen to him.
- **Objective**: Survival. Kai establishes a **Micro Farm**.
- **Meeting Gronk**: Kai saves Gronk from a trap. Gronk pledges loyalty and explains that Ana is still alive, leaving "signs" for Kai.
- **The Plan**: Build a base, gather resources, and find the **50 Clues** Ana left behind.
### 🗺️ Act 2: The Journey (Biomes 1-18)
Kai travels through 18 distinct biomes (Forests, Swamps, Deserts, Ruins), restoring civilization town by town.
- **Mechanic**: Kai clears areas, rebuilds towns, and sets up "Zombie Workforce" automation.
- **The Clues**: He finds pages of Ana's diary, torn fabric, and encoded messages. Each clue reveals she is being moved closer to the "Old Zone" (Chernobyl).
- **Bosses**: Kai defeats regional guardians (Mutant King, Zombie Horde Leader, Ancient Tree) who guard the path forward.
### 🔬 Act 3: The Revelation (The Bio-Lab)
Kai gathers enough clues to locate Krnić's secret forward base.
- **Infiltration**: He storms the lab.
- **The Twist**: He finds Ana's cell... empty. A video log reveals Krnić has moved her to **Chernobyl** for the "Final Stage" of his experiment.
- **The Stakes**: Krnić plans to release a Super Virus that will wipe out all non-hybrids.
### ☢️ Act 4: The Reactor (Chernobyl)
The Finale. Kai and Gronk travel to the irradiated ruins of Pripyat.
- **Final Battle**: Kai faces the **Giant Troll King** (Gronk's Cousin) in a massive showdown.
- **The Confrontation**: Kai confronts Dr. Krnić at the Reactor Core.
---
## 🏁 The Endings (Based on Player Choice)
1. **🌟 Together Forever (True Ending)**
* **Condition**: All 50 Clues found, Cure synthesized.
* **Outcome**: Kai rescues Ana. They defeat Krnić and use the cure to stabilize the world. Humans and Hybrids live in peace.
2. **💔 The Sacrifice**
* **Condition**: Kai saves Ana but takes a fatal blow.
* **Outcome**: Kai dies a hero's death. Ana survives to lead the new world, building a statue in his honor.
3. **😢 The Hermit (Bad Ending)**
* **Condition**: Ana dies during the rescue.
* **Outcome**: Kai is broken. He returns to his farm, isolates himself, and lives out his days in silence with only his zombie workers.
4. **💀 The Tyrant (Evil Ending)**
* **Condition**: Kai embraces the darkness/power.
* **Outcome**: Kai kills Krnić but takes his place. He rules the wasteland as the "Zombie King," with Ana leading the resistance against him.

500
preview_animations.html Normal file
View File

@@ -0,0 +1,500 @@
<!DOCTYPE html>
<html lang="sl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DolinaSmrti - Character Animation Preview</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
color: #fff;
padding: 20px;
}
.header {
text-align: center;
padding: 40px 20px;
background: rgba(255, 255, 255, 0.05);
border-radius: 15px;
margin-bottom: 40px;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.header h1 {
font-size: 3em;
margin-bottom: 10px;
background: linear-gradient(45deg, #00ff88, #00ddff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.header p {
font-size: 1.2em;
color: #aaa;
}
.stats {
display: flex;
justify-content: center;
gap: 30px;
margin: 20px 0;
flex-wrap: wrap;
}
.stat-box {
background: rgba(0, 255, 136, 0.1);
padding: 15px 30px;
border-radius: 10px;
border: 2px solid rgba(0, 255, 136, 0.3);
}
.stat-box .number {
font-size: 2em;
font-weight: bold;
color: #00ff88;
}
.stat-box .label {
font-size: 0.9em;
color: #aaa;
text-transform: uppercase;
}
.controls {
background: rgba(255, 255, 255, 0.05);
padding: 20px;
border-radius: 10px;
margin-bottom: 30px;
display: flex;
gap: 15px;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 1em;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 600;
}
.btn-primary {
background: linear-gradient(45deg, #00ff88, #00ddff);
color: #000;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(0, 255, 136, 0.4);
}
.btn-secondary {
background: rgba(255, 255, 255, 0.1);
color: #fff;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.2);
}
.character-section {
margin-bottom: 60px;
}
.character-header {
background: rgba(255, 255, 255, 0.08);
padding: 20px 30px;
border-radius: 10px;
margin-bottom: 20px;
border-left: 5px solid;
}
.character-header.kai {
border-color: #00ff88;
}
.character-header.ana {
border-color: #ff00ff;
}
.character-header.gronk {
border-color: #00ddff;
}
.character-header h2 {
font-size: 2em;
margin-bottom: 10px;
}
.character-header .info {
color: #aaa;
font-size: 1.1em;
}
.animation-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.animation-card {
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 15px;
border: 2px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.animation-card:hover {
transform: translateY(-5px);
border-color: rgba(0, 255, 136, 0.5);
box-shadow: 0 10px 30px rgba(0, 255, 136, 0.2);
}
.animation-card h3 {
font-size: 1.2em;
margin-bottom: 10px;
color: #00ff88;
}
.frames-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 10px;
margin-top: 15px;
}
.frame-box {
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
padding: 8px;
text-align: center;
}
.frame-box img {
width: 100%;
height: auto;
border-radius: 5px;
background: rgba(255, 255, 255, 0.05);
cursor: pointer;
transition: transform 0.2s ease;
}
.frame-box img:hover {
transform: scale(1.05);
}
.frame-box .frame-label {
font-size: 0.8em;
color: #aaa;
margin-top: 5px;
}
.loading {
text-align: center;
padding: 40px;
font-size: 1.5em;
color: #00ff88;
}
.loading::after {
content: '...';
animation: dots 1.5s infinite;
}
@keyframes dots {
0%,
20% {
content: '.';
}
40% {
content: '..';
}
60%,
100% {
content: '...';
}
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal.active {
display: flex;
}
.modal-content {
max-width: 90%;
max-height: 90%;
}
.modal-content img {
width: 100%;
height: auto;
border-radius: 10px;
}
.close-modal {
position: absolute;
top: 20px;
right: 40px;
font-size: 3em;
color: #fff;
cursor: pointer;
z-index: 1001;
}
</style>
</head>
<body>
<div class="header">
<h1>🎮 DolinaSmrti - Character Animations</h1>
<p>Complete Animation Preview - Bloody Harvest</p>
<div class="stats">
<div class="stat-box">
<div class="number" id="total-animations">0</div>
<div class="label">Animations</div>
</div>
<div class="stat-box">
<div class="number" id="total-frames">0</div>
<div class="label">Frames</div>
</div>
<div class="stat-box">
<div class="number" id="total-files">0</div>
<div class="label">Files</div>
</div>
</div>
</div>
<div class="controls">
<button class="btn btn-primary" onclick="loadAllAnimations()">🔄 Refresh Gallery</button>
<button class="btn btn-secondary" onclick="filterCharacter('all')">All Characters</button>
<button class="btn btn-secondary" onclick="filterCharacter('kai')">Kai Only</button>
<button class="btn btn-secondary" onclick="filterCharacter('ana')">Ana Only</button>
<button class="btn btn-secondary" onclick="filterCharacter('gronk')">Gronk Only</button>
<button class="btn btn-secondary" onclick="togglePreviewSize()">Toggle Size</button>
</div>
<div id="content">
<div class="loading">Loading animations</div>
</div>
<div class="modal" id="modal" onclick="closeModal()">
<span class="close-modal">&times;</span>
<div class="modal-content">
<img id="modal-img" src="" alt="">
</div>
</div>
<script>
const CHARACTERS = {
'kai': {
name: 'Kai Marković',
color: '#00ff88',
desc: 'Zombie Whisperer - Age 17'
},
'ana': {
name: 'Ana Marković',
color: '#ff00ff',
desc: 'Twin Sister - Scientist - Age 17'
},
'gronk': {
name: 'Gronk',
color: '#00ddff',
desc: 'Zen Troll Companion'
}
};
let currentFilter = 'all';
let previewSize = 'preview';
async function loadAllAnimations() {
const content = document.getElementById('content');
content.innerHTML = '<div class="loading">Loading animations</div>';
let totalAnimations = 0;
let totalFrames = 0;
let totalFiles = 0;
let html = '';
for (const [charKey, charData] of Object.entries(CHARACTERS)) {
try {
const response = await fetch(`../assets/slike/${charKey}/`);
const text = await response.text();
// Parse directory listing for PNG files
const parser = new DOMParser();
const doc = parser.parseFromString(text, 'text/html');
const links = doc.querySelectorAll('a');
const animations = {};
// Group files by animation name
links.forEach(link => {
const filename = link.textContent;
if (filename.includes('_preview_256x256.png')) {
const match = filename.match(/(.+)_frame(\d+)_preview/);
if (match) {
const animName = match[1].replace(`${charKey}_`, '');
const frameNum = parseInt(match[2]);
if (!animations[animName]) {
animations[animName] = [];
}
animations[animName].push({
frame: frameNum,
preview: filename,
original: filename.replace('_preview_256x256.png', '_1024x1024.png')
});
}
}
});
// Sort frames
Object.keys(animations).forEach(animName => {
animations[animName].sort((a, b) => a.frame - b.frame);
});
totalAnimations += Object.keys(animations).length;
// Generate HTML for this character
html += `
<div class="character-section" data-character="${charKey}">
<div class="character-header ${charKey}">
<h2>${charData.name}</h2>
<div class="info">${charData.desc} - ${Object.keys(animations).length} animations</div>
</div>
<div class="animation-grid">
`;
Object.entries(animations).forEach(([animName, frames]) => {
totalFrames += frames.length;
totalFiles += frames.length * 2; // preview + original
html += `
<div class="animation-card">
<h3>${animName}</h3>
<div class="frames-container">
`;
frames.forEach(frame => {
html += `
<div class="frame-box">
<img src="../assets/slike/${charKey}/${frame.preview}"
alt="${animName} frame ${frame.frame}"
onclick="openModal('../assets/slike/${charKey}/${frame.original}')">
<div class="frame-label">Frame ${frame.frame}</div>
</div>
`;
});
html += `
</div>
</div>
`;
});
html += `
</div>
</div>
`;
} catch (error) {
console.error(`Error loading ${charKey}:`, error);
}
}
content.innerHTML = html || '<div class="loading">No animations found. Run generation script first!</div>';
// Update stats
document.getElementById('total-animations').textContent = totalAnimations;
document.getElementById('total-frames').textContent = totalFrames;
document.getElementById('total-files').textContent = totalFiles;
}
function filterCharacter(filter) {
currentFilter = filter;
const sections = document.querySelectorAll('.character-section');
sections.forEach(section => {
if (filter === 'all' || section.dataset.character === filter) {
section.style.display = 'block';
} else {
section.style.display = 'none';
}
});
}
function togglePreviewSize() {
const images = document.querySelectorAll('.frame-box img');
if (previewSize === 'preview') {
previewSize = 'large';
images.forEach(img => {
img.src = img.src.replace('_preview_256x256.png', '_1024x1024.png');
});
} else {
previewSize = 'preview';
images.forEach(img => {
img.src = img.src.replace('_1024x1024.png', '_preview_256x256.png');
});
}
}
function openModal(imageSrc) {
const modal = document.getElementById('modal');
const modalImg = document.getElementById('modal-img');
modalImg.src = imageSrc;
modal.classList.add('active');
}
function closeModal() {
const modal = document.getElementById('modal');
modal.classList.remove('active');
}
// Auto-load on page load
window.addEventListener('load', () => {
loadAllAnimations();
// Auto-refresh every 30 seconds during generation
setInterval(() => {
if (document.visibilityState === 'visible') {
loadAllAnimations();
}
}, 30000);
});
</script>
</body>
</html>

View File

@@ -0,0 +1,393 @@
#!/usr/bin/env python3
"""
COMPLETE CHARACTER ANIMATION GENERATOR
Generates ALL animations for Kai, Ana, and Gronk (435 PNG total)
Date: 1.1.2026
"""
import os
import time
from pathlib import Path
import google.generativeai as genai
from PIL import Image
import io
# ==================== CONFIGURATION ====================
# Try both environment variable names
API_KEY = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY')
if not API_KEY:
print("❌ ERROR: API key not found!")
print("Please set one of:")
print(" export GEMINI_API_KEY='your-key-here'")
print(" export GOOGLE_API_KEY='your-key-here'")
raise ValueError("API key not set!")
# NOTE: Using deprecated google.generativeai for compatibility
# TODO: Migrate to google.genai in future
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
genai.configure(api_key=API_KEY)
print(f"✅ API Key configured (first 10 chars): {API_KEY[:10]}...")
OUTPUT_DIR = Path("assets/slike")
DELAY_BETWEEN_CALLS = 15 # seconds (safe rate limiting)
# Art Style Constants
STYLE_BASE = """
Dark Hand-Drawn 2D Stylized Indie Game Art.
CRITICAL REQUIREMENTS:
- THICK bold black outlines (3-4px)
- Exaggerated proportions, warped perspective
- High-contrast noir elements
- Centered subject with 10px transparent margin
- 32-bit PNG with alpha channel
- Clean background (pure transparency)
"""
# ==================== CHARACTER DEFINITIONS ====================
KAI_BASE = """
Character: KAI MARKOVIĆ (Age 17, Male Protagonist)
- Green & Pink dreadlocks (distinctive!)
- Tactical survivor outfit (torn, weathered)
- Lean athletic build
- Determined expression
- REFERENCE: Check konsistentno/kai_master_styleA_reference.png
"""
ANA_BASE = """
Character: ANA MARKOVIĆ (Age 17, Female Twin)
- Pink dreadlocks (matches Kai's style but all pink)
- Explorer vest, cargo pants
- Slender athletic build
- Intelligent, caring expression
- REFERENCE: Check konsistentno/ana_master_styleA_reference.png
"""
GRONK_BASE = """
Character: GRONK (Zen Troll Companion)
- Large green troll, 7ft tall
- Pink mohawk hair
- Multiple piercings (ears, nose)
- Vape pen accessory (signature item!)
- Baggy pants, no shirt
- Chill, relaxed expression
- REFERENCE: Check konsistentno/gronk_master_styleA_reference.png
"""
# ==================== ANIMATION DEFINITIONS ====================
KAI_ANIMATIONS = {
# PHASE 1: Core Gameplay (72 PNG)
"walk_north": {"frames": 4, "desc": "walking away from camera, back view"},
"walk_northeast": {"frames": 4, "desc": "walking diagonal up-right"},
"walk_east": {"frames": 4, "desc": "walking right, side view (right profile)"},
"walk_southeast": {"frames": 4, "desc": "walking diagonal down-right"},
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
"walk_southwest": {"frames": 4, "desc": "walking diagonal down-left"},
"walk_west": {"frames": 4, "desc": "walking left, side view (left profile)"},
"walk_northwest": {"frames": 4, "desc": "walking diagonal up-left"},
"idle_front": {"frames": 4, "desc": "idle standing, front view, breathing animation"},
"idle_side": {"frames": 4, "desc": "idle standing, side profile, breathing animation"},
"attack_north": {"frames": 4, "desc": "sword swing upward (attacking north)"},
"attack_east": {"frames": 4, "desc": "sword swing right (attacking east)"},
"attack_south": {"frames": 4, "desc": "sword swing downward (attacking south)"},
"attack_west": {"frames": 4, "desc": "sword swing left (attacking west)"},
"dig_north": {"frames": 4, "desc": "digging with shovel upward"},
"dig_east": {"frames": 4, "desc": "digging with shovel to the right"},
"dig_south": {"frames": 4, "desc": "digging with shovel downward"},
"dig_west": {"frames": 4, "desc": "digging with shovel to the left"},
# PHASE 2: Expanded (47 PNG)
"run_north": {"frames": 4, "desc": "running away, back view, faster pace"},
"run_northeast": {"frames": 4, "desc": "running diagonal up-right"},
"run_east": {"frames": 4, "desc": "running right, side view"},
"run_southeast": {"frames": 4, "desc": "running diagonal down-right"},
"run_south": {"frames": 4, "desc": "running toward camera, front view"},
"run_southwest": {"frames": 4, "desc": "running diagonal down-left"},
"run_west": {"frames": 4, "desc": "running left, side view"},
"run_northwest": {"frames": 4, "desc": "running diagonal up-left"},
"plant_front": {"frames": 3, "desc": "planting seeds, kneeling, front view"},
"plant_side": {"frames": 3, "desc": "planting seeds, kneeling, side view"},
"harvest_front": {"frames": 3, "desc": "harvesting crops, bending down, front view"},
"harvest_side": {"frames": 3, "desc": "harvesting crops, bending down, side view"},
"hurt": {"frames": 3, "desc": "taking damage, recoiling, pain expression"},
# PHASE 3: Polish (27 PNG)
"sad": {"frames": 4, "desc": "crying, hands on face, emotional"},
"happy": {"frames": 4, "desc": "celebrating, arms raised, joyful"},
"thinking": {"frames": 3, "desc": "hand on chin, pondering"},
"shocked": {"frames": 2, "desc": "surprised, eyes wide, mouth open"},
"use_item_front": {"frames": 3, "desc": "using item from inventory, front view"},
"use_item_side": {"frames": 3, "desc": "using item from inventory, side view"},
"eat": {"frames": 3, "desc": "eating food, bringing to mouth"},
"death": {"frames": 5, "desc": "death animation, collapsing to ground"},
# PHASE 4: Advanced (10 PNG)
"zombie_command": {"frames": 4, "desc": "telepathic gesture, hand raised, concentration"},
"telepathy_effect": {"frames": 6, "desc": "psychic energy emanating, glowing effect"},
}
ANA_ANIMATIONS = {
# PHASE 1: Core (56 PNG)
"walk_north": {"frames": 4, "desc": "walking away, back view"},
"walk_northeast": {"frames": 4, "desc": "walking diagonal up-right"},
"walk_east": {"frames": 4, "desc": "walking right, side view"},
"walk_southeast": {"frames": 4, "desc": "walking diagonal down-right"},
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
"walk_southwest": {"frames": 4, "desc": "walking diagonal down-left"},
"walk_west": {"frames": 4, "desc": "walking left, side view"},
"walk_northwest": {"frames": 4, "desc": "walking diagonal up-left"},
"idle_front": {"frames": 4, "desc": "idle standing, front view"},
"idle_side": {"frames": 4, "desc": "idle standing, side profile"},
"research_front": {"frames": 4, "desc": "writing in notebook, studying"},
"research_side": {"frames": 4, "desc": "writing in notebook, side view"},
"heal_front": {"frames": 4, "desc": "applying bandage, medical care"},
"heal_side": {"frames": 4, "desc": "applying bandage, side view"},
# PHASE 2: Expanded (46 PNG)
"run_north": {"frames": 4, "desc": "running away, back view"},
"run_northeast": {"frames": 4, "desc": "running diagonal up-right"},
"run_east": {"frames": 4, "desc": "running right"},
"run_southeast": {"frames": 4, "desc": "running diagonal down-right"},
"run_south": {"frames": 4, "desc": "running toward camera"},
"run_southwest": {"frames": 4, "desc": "running diagonal down-left"},
"run_west": {"frames": 4, "desc": "running left"},
"run_northwest": {"frames": 4, "desc": "running diagonal up-left"},
"examine_front": {"frames": 3, "desc": "examining with magnifying glass"},
"examine_side": {"frames": 3, "desc": "examining, side view"},
"mix_potion": {"frames": 4, "desc": "mixing ingredients in flask"},
"worried": {"frames": 4, "desc": "worried expression, hand to head"},
# PHASE 3: Polish (18 PNG)
"relief": {"frames": 4, "desc": "relief, exhaling, relaxed"},
"twin_bond_glow": {"frames": 6, "desc": "glowing psychic connection effect"},
"flashback_pose": {"frames": 3, "desc": "memory pose, ethereal"},
"death": {"frames": 5, "desc": "death animation, collapsing"},
# PHASE 4: Advanced (18 PNG)
"collect_sample_front": {"frames": 3, "desc": "collecting sample with vial"},
"collect_sample_side": {"frames": 3, "desc": "collecting sample, side view"},
"defend": {"frames": 4, "desc": "defensive stance with staff"},
"cure_cast": {"frames": 5, "desc": "casting cure spell, magical gesture"},
"hurt": {"frames": 3, "desc": "taking damage, recoiling"},
}
GRONK_ANIMATIONS = {
# PHASE 1: Core (72 PNG)
"walk_north": {"frames": 4, "desc": "heavy lumbering walk, back view"},
"walk_northeast": {"frames": 4, "desc": "heavy walk diagonal up-right"},
"walk_east": {"frames": 4, "desc": "heavy walk right, side view"},
"walk_southeast": {"frames": 4, "desc": "heavy walk diagonal down-right"},
"walk_south": {"frames": 4, "desc": "heavy walk toward camera, front view"},
"walk_southwest": {"frames": 4, "desc": "heavy walk diagonal down-left"},
"walk_west": {"frames": 4, "desc": "heavy walk left, side view"},
"walk_northwest": {"frames": 4, "desc": "heavy walk diagonal up-left"},
"idle_front": {"frames": 4, "desc": "idle, chill stance, front view"},
"idle_side": {"frames": 4, "desc": "idle, chill stance, side view"},
"vape_front": {"frames": 6, "desc": "vaping, exhaling smoke cloud, front view"},
"vape_side": {"frames": 6, "desc": "vaping, exhaling smoke, side view"},
"smash_north": {"frames": 5, "desc": "club smash upward"},
"smash_east": {"frames": 5, "desc": "club smash right"},
"smash_south": {"frames": 5, "desc": "club smash downward"},
"smash_west": {"frames": 5, "desc": "club smash left"},
# PHASE 2: Expanded (47 PNG)
"run_north": {"frames": 4, "desc": "slow lumbering run, back view"},
"run_northeast": {"frames": 4, "desc": "lumbering run diagonal up-right"},
"run_east": {"frames": 4, "desc": "lumbering run right"},
"run_southeast": {"frames": 4, "desc": "lumbering run diagonal down-right"},
"run_south": {"frames": 4, "desc": "lumbering run toward camera"},
"run_southwest": {"frames": 4, "desc": "lumbering run diagonal down-left"},
"run_west": {"frames": 4, "desc": "lumbering run left"},
"run_northwest": {"frames": 4, "desc": "lumbering run diagonal up-left"},
"lift_heavy_front": {"frames": 4, "desc": "lifting heavy object, straining"},
"lift_heavy_side": {"frames": 4, "desc": "lifting heavy object, side view"},
"laugh": {"frames": 4, "desc": "laughing, belly laugh, jovial"},
"hurt": {"frames": 3, "desc": "taking damage, grimacing"},
# PHASE 3: Polish (16 PNG)
"meditate": {"frames": 4, "desc": "zen meditation pose, sitting, serene"},
"confused": {"frames": 3, "desc": "confused, scratching head"},
"chill": {"frames": 3, "desc": "ultra relaxed, peace sign"},
"death": {"frames": 5, "desc": "death animation, collapsing heavily"},
# PHASE 4: Advanced (6 PNG)
"block": {"frames": 3, "desc": "blocking with raised arms"},
"taunt": {"frames": 4, "desc": "taunting enemies, beckoning"},
}
# ==================== GENERATION FUNCTIONS ====================
def generate_animation_frame(character_name, character_base, animation_name, frame_num, animation_desc, style=STYLE_BASE):
"""Generate a single animation frame"""
prompt = f"""
{style}
{character_base}
ANIMATION: {animation_name} - Frame {frame_num}
Description: {animation_desc}
Frame {frame_num} timing notes:
- Frame 1: Start pose
- Frame 2: Mid-motion
- Frame 3: Peak/impact
- Frame 4: Follow-through/return
Generate this specific frame showing clear progression in the animation cycle.
Maintain character consistency (check reference in konsistentno/ folder).
"""
try:
print(f" 🎨 Generating {character_name} - {animation_name} - Frame {frame_num}...")
model = genai.GenerativeModel('gemini-2.0-flash-exp')
response = model.generate_content([prompt])
if response.parts and len(response.parts) > 0:
image_data = response.parts[0].inline_data.data
image = Image.open(io.BytesIO(image_data))
return image
else:
print(f" ❌ No image generated for {animation_name} frame {frame_num}")
return None
except Exception as e:
print(f" ❌ Error generating {animation_name} frame {frame_num}: {e}")
return None
def generate_character_animations(character_name, character_base, animations_dict):
"""Generate all animations for a character"""
char_dir = OUTPUT_DIR / character_name.lower()
char_dir.mkdir(parents=True, exist_ok=True)
total_frames = sum(anim["frames"] for anim in animations_dict.values())
current_frame = 0
print(f"\n{'='*60}")
print(f"🎬 GENERATING {character_name.upper()} ANIMATIONS")
print(f"{'='*60}")
print(f"Total animations: {len(animations_dict)}")
print(f"Total frames: {total_frames}")
print(f"Output directory: {char_dir}")
print()
for anim_name, anim_data in animations_dict.items():
frames_count = anim_data["frames"]
desc = anim_data["desc"]
print(f"\n📹 Animation: {anim_name} ({frames_count} frames)")
for frame_num in range(1, frames_count + 1):
current_frame += 1
# Generate frame
image = generate_animation_frame(
character_name,
character_base,
anim_name,
frame_num,
desc
)
if image:
# Save original
filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_1024x1024.png"
filepath = char_dir / filename
image.save(filepath, "PNG")
print(f" ✅ Saved: {filename}")
# Create preview (256x256)
preview = image.resize((256, 256), Image.Resampling.LANCZOS)
preview_filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_preview_256x256.png"
preview_filepath = char_dir / preview_filename
preview.save(preview_filepath, "PNG")
print(f" ✅ Saved preview: {preview_filename}")
# Progress
progress = (current_frame / total_frames) * 100
print(f" 📊 Progress: {current_frame}/{total_frames} ({progress:.1f}%)")
# Rate limiting
print(f" ⏳ Waiting {DELAY_BETWEEN_CALLS}s...")
time.sleep(DELAY_BETWEEN_CALLS)
print(f"\n{character_name.upper()} COMPLETE! Generated {total_frames} frames ({total_frames * 2} files with previews)")
return total_frames
# ==================== MAIN EXECUTION ====================
def main():
"""Generate all character animations"""
print("=" * 80)
print("🎮 DOLINASMRTI - COMPLETE CHARACTER ANIMATION GENERATOR")
print("=" * 80)
print(f"Date: 2026-01-01")
print(f"Target: 435 PNG (all 3 characters, all animations)")
print(f"API Delay: {DELAY_BETWEEN_CALLS}s between calls")
print()
start_time = time.time()
total_generated = 0
# Generate Kai
kai_frames = generate_character_animations("Kai", KAI_BASE, KAI_ANIMATIONS)
total_generated += kai_frames
# Generate Ana
ana_frames = generate_character_animations("Ana", ANA_BASE, ANA_ANIMATIONS)
total_generated += ana_frames
# Generate Gronk
gronk_frames = generate_character_animations("Gronk", GRONK_BASE, GRONK_ANIMATIONS)
total_generated += gronk_frames
# Summary
elapsed = time.time() - start_time
hours = int(elapsed // 3600)
minutes = int((elapsed % 3600) // 60)
print("\n" + "=" * 80)
print("🎆 GENERATION COMPLETE!")
print("=" * 80)
print(f"Total frames generated: {total_generated}")
print(f"Total files created: {total_generated * 2} (with previews)")
print(f"Time elapsed: {hours}h {minutes}min")
print(f"\nCharacter breakdown:")
print(f" - Kai: {kai_frames} frames")
print(f" - Ana: {ana_frames} frames")
print(f" - Gronk: {gronk_frames} frames")
print("\n✅ All character animations ready for game integration!")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,259 @@
#!/usr/bin/env python3
"""
CHARACTER ANIMATION GENERATOR - WORKING VERSION
Uses direct REST API instead of deprecated SDK
Generates animations for Kai, Ana, Gronk
Date: 1.1.2026
"""
import os
import time
import json
import base64
from pathlib import Path
import requests
from PIL import Image
import io
# ==================== CONFIGURATION ====================
API_KEY = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY')
if not API_KEY:
print("❌ ERROR: API key not found!")
print("Please set: export GEMINI_API_KEY='your-key-here'")
exit(1)
print(f"✅ API Key found: {API_KEY[:10]}...")
OUTPUT_DIR = Path("assets/slike")
DELAY_BETWEEN_CALLS = 15 # seconds
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent"
# ==================== STYLE CONSTANTS ====================
STYLE_BASE = """Dark Hand-Drawn 2D Stylized Indie Game Art.
CRITICAL: Thick bold black outlines (3-4px), exaggerated proportions, warped perspective.
High-contrast noir elements. Centered subject with 10px transparent margin.
32-bit PNG with alpha channel. Clean background (pure transparency)."""
KAI_BASE = """Character: KAI MARKOVIĆ (Age 17, Male Protagonist)
- Green & Pink dreadlocks (distinctive!)
- Tactical survivor outfit (torn, weathered)
- Lean athletic build, determined expression"""
ANA_BASE = """Character: ANA MARKOVIĆ (Age 17, Female Twin)
- Pink dreadlocks (all pink, matches Kai's style)
- Explorer vest, cargo pants
- Slender athletic build, intelligent caring expression"""
GRONK_BASE = """Character: GRONK (Zen Troll Companion)
- Large green troll, 7ft tall
- Pink mohawk hair, multiple piercings
- Vape pen accessory (signature!)
- Baggy pants, no shirt, chill relaxed expression"""
# ==================== SIMPLIFIED ANIMATION SET ====================
# Start with essentials only to test the system
KAI_ANIMATIONS = {
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
"walk_east": {"frames": 4, "desc": "walking right, side view"},
"idle_front": {"frames": 4, "desc": "idle standing, front view, breathing"},
"attack_south": {"frames": 4, "desc": "sword swing downward"},
}
ANA_ANIMATIONS = {
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
"walk_east": {"frames": 4, "desc": "walking right, side view"},
"idle_front": {"frames": 4, "desc": "idle standing, front view"},
"research_front": {"frames": 4, "desc": "writing in notebook"},
}
GRONK_ANIMATIONS = {
"walk_south": {"frames": 4, "desc": "heavy lumbering walk, front view"},
"walk_east": {"frames": 4, "desc": "heavy walk right, side view"},
"idle_front": {"frames": 4, "desc": "idle, chill stance, front view"},
"vape_front": {"frames": 6, "desc": "vaping, exhaling smoke cloud"},
}
# ==================== GENERATION FUNCTIONS ====================
def generate_image_rest_api(prompt):
"""Generate image using REST API"""
payload = {
"contents": [{
"parts": [{
"text": prompt
}]
}],
"generationConfig": {
"temperature": 0.4,
"topK": 32,
"topP": 1,
"maxOutputTokens": 4096,
}
}
headers = {
"Content-Type": "application/json"
}
url = f"{API_URL}?key={API_KEY}"
try:
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
data = response.json()
# Extract image from response
if 'candidates' in data and len(data['candidates']) > 0:
candidate = data['candidates'][0]
if 'content' in candidate and 'parts' in candidate['content']:
for part in candidate['content']['parts']:
if 'inlineData' in part:
image_b64 = part['inlineData']['data']
image_bytes = base64.b64decode(image_b64)
image = Image.open(io.BytesIO(image_bytes))
return image
print(f" ❌ No image in response")
return None
except requests.exceptions.RequestException as e:
print(f" ❌ API Error: {e}")
return None
except Exception as e:
print(f" ❌ Error: {e}")
return None
def generate_animation_frame(character_name, character_base, animation_name, frame_num, animation_desc):
"""Generate a single animation frame"""
prompt = f"""{STYLE_BASE}
{character_base}
ANIMATION: {animation_name} - Frame {frame_num}/4
Description: {animation_desc}
Frame timing:
- Frame 1: Start pose
- Frame 2: Mid-motion
- Frame 3: Peak/impact
- Frame 4: Follow-through
Generate this specific frame showing clear progression.
Maintain character consistency."""
print(f" 🎨 {character_name} - {animation_name} - Frame {frame_num}...")
image = generate_image_rest_api(prompt)
return image
def generate_character_animations(character_name, character_base, animations_dict):
"""Generate all animations for a character"""
char_dir = OUTPUT_DIR / character_name.lower()
char_dir.mkdir(parents=True, exist_ok=True)
total_frames = sum(anim["frames"] for anim in animations_dict.values())
current_frame = 0
print(f"\n{'='*60}")
print(f"🎬 GENERATING {character_name.upper()}")
print(f"{'='*60}")
print(f"Animations: {len(animations_dict)}")
print(f"Total frames: {total_frames}")
print(f"Output: {char_dir}\n")
for anim_name, anim_data in animations_dict.items():
frames_count = anim_data["frames"]
desc = anim_data["desc"]
print(f"\n📹 {anim_name} ({frames_count} frames)")
for frame_num in range(1, frames_count + 1):
current_frame += 1
image = generate_animation_frame(
character_name,
character_base,
anim_name,
frame_num,
desc
)
if image:
# Save original
filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_1024x1024.png"
filepath = char_dir / filename
image.save(filepath, "PNG")
print(f" ✅ Saved: {filename}")
# Create preview
preview = image.resize((256, 256), Image.Resampling.LANCZOS)
preview_filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_preview_256x256.png"
preview_filepath = char_dir / preview_filename
preview.save(preview_filepath, "PNG")
print(f" ✅ Preview: {preview_filename}")
# Progress
progress = (current_frame / total_frames) * 100
print(f" 📊 Progress: {current_frame}/{total_frames} ({progress:.1f}%)")
# Rate limiting
if current_frame < total_frames:
print(f" ⏳ Waiting {DELAY_BETWEEN_CALLS}s...")
time.sleep(DELAY_BETWEEN_CALLS)
print(f"\n{character_name.upper()} COMPLETE!")
print(f"Generated: {total_frames} frames ({total_frames * 2} files)\n")
return total_frames
# ==================== MAIN ====================
def main():
print("=" * 80)
print("🎮 DOLINASMRTI - CHARACTER ANIMATION GENERATOR")
print("=" * 80)
print("Date: 2026-01- 01")
print("Mode: ESSENTIAL ANIMATIONS TEST")
print(f"API Delay: {DELAY_BETWEEN_CALLS}s\n")
start_time = time.time()
total_generated = 0
# Generate essentials for each character
kai_frames = generate_character_animations("Kai", KAI_BASE, KAI_ANIMATIONS)
total_generated += kai_frames
ana_frames = generate_character_animations("Ana", ANA_BASE, ANA_ANIMATIONS)
total_generated += ana_frames
gronk_frames = generate_character_animations("Gronk", GRONK_BASE, GRONK_ANIMATIONS)
total_generated += gronk_frames
# Summary
elapsed = time.time() - start_time
hours = int(elapsed // 3600)
minutes = int((elapsed % 3600) // 60)
print("\n" + "=" * 80)
print("🎆 GENERATION COMPLETE!")
print("=" * 80)
print(f"Total frames: {total_generated}")
print(f"Total files: {total_generated * 2}")
print(f"Time: {hours}h {minutes}min")
print(f"\nBreakdown:")
print(f" - Kai: {kai_frames} frames")
print(f" - Ana: {ana_frames} frames")
print(f" - Gronk: {gronk_frames} frames")
print("\n✅ Ready for game integration!")
print("\n💡 View in Chrome: open preview_animations.html")
if __name__ == "__main__":
main()

68
scripts/test_imagen.py Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python3
"""
TEST - Imagen 3 API (Image Generation)
"""
import os
import requests
import base64
from PIL import Image
import io
API_KEY = os.getenv('GEMINI_API_KEY')
print(f"✅ API Key: {API_KEY[:15]}...")
# Use Imagen 3 endpoint
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict"
prompt = "Dark hand-drawn 2D stylized indie game art. Character KAI - male, age 17, green and pink dreadlocks, tactical survivor outfit. Walking toward camera, front view. Bold black outlines, centered, transparent background."
print(f"\n🎨 Generating with Imagen 3...")
print(f"Prompt: {prompt[:80]}...\n")
payload = {
"instances": [{
"prompt": prompt
}],
"parameters": {
"sampleCount": 1,
"aspectRatio": "1:1",
"mode": "generateImages"
}
}
headers = {"Content-Type": "application/json"}
url = f"{API_URL}?key={API_KEY}"
print(f"📡 Calling Imagen API...")
try:
response = requests.post(url, headers=headers, json=payload, timeout=60)
print(f"Status: {response.status_code}")
if response.status_code == 200:
data = response.json()
print(f"✅ Response received!")
print(f"Response keys: {list(data.keys())}")
if 'predictions' in data and len(data['predictions']) > 0:
pred = data['predictions'][0]
print(f"Prediction keys: {list(pred.keys())}")
if 'bytesBase64Encoded' in pred:
print(f"✅ Found image data!")
image_b64 = pred['bytesBase64Encoded']
image_bytes = base64.b64decode(image_b64)
image = Image.open(io.BytesIO(image_bytes))
output_path = "assets/slike/TEST_kai_imagen.png"
image.save(output_path, "PNG")
print(f"✅✅ SAVED: {output_path}")
print(f"Image size: {image.size}")
else:
print(f"Response data: {data}")
else:
print(f"❌ Error {response.status_code}: {response.text}")
except Exception as e:
print(f"❌ Exception: {e}")
print("\n✅ Test complete!")

68
scripts/test_minimal.py Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python3
"""
MINIMAL TEST - Generate ONE image
"""
import os
import requests
import json
import base64
from PIL import Image
import io
API_KEY = os.getenv('GEMINI_API_KEY')
print(f"✅ API Key: {API_KEY[:15]}...")
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent"
prompt = """Dark Hand-Drawn 2D Stylized Indie Game Art.
Character: KAI - Green & Pink dreadlocks, tactical outfit, age 17.
Animation: Walking toward camera, frame 1 of 4, front view.
Bold black outlines, centered, transparent background."""
print(f"\n🎨 Generating test image...")
print(f"Prompt: {prompt[:80]}...\n")
payload = {
"contents": [{
"parts": [{
"text": prompt
}]
}]
}
headers = {"Content-Type": "application/json"}
url = f"{API_URL}?key={API_KEY}"
print(f"📡 Calling API...")
response = requests.post(url, headers=headers, json=payload, timeout=60)
print(f"Status: {response.status_code}")
if response.status_code == 200:
data = response.json()
print(f"✅ Response received!")
print(f"Keys: {list(data.keys())}")
if 'candidates' in data:
print(f"Candidates: {len(data['candidates'])}")
for i, cand in enumerate(data['candidates']):
print(f"\nCandidate {i}:")
if 'content' in cand:
print(f" Content keys: {list(cand['content'].keys())}")
if 'parts' in cand['content']:
print(f" Parts: {len(cand['content']['parts'])}")
for j, part in enumerate(cand['content']['parts']):
print(f" Part {j} keys: {list(part.keys())}")
if 'inlineData' in part:
print(f" ✅ Found image data!")
image_b64 = part['inlineData']['data']
image_bytes = base64.b64decode(image_b64)
image = Image.open(io.BytesIO(image_bytes))
output_path = "assets/slike/TEST_kai_walk_frame1.png"
image.save(output_path, "PNG")
print(f" ✅✅ Saved to: {output_path}")
else:
print(f"❌ Error: {response.text}")
print("\n✅ Test complete!")