docs: Director Mode v1.0 - Master Directive & Implementation Plan
Added comprehensive directive and implementation plan for v1.0 release: - Political systems (Lawyer, Mayor) - Work automation (Zombie workers, 4-frame animations) - Cinematic intro (Ken Burns, typewriter, blur-to-clear) - Accessibility (ADHD mode, colorblind filters, asset gallery) Current asset count: 1200+ images Latest batch: 342 Style 32 assets Status: Ready for autonomous execution
This commit is contained in:
297
.agent/workflows/v1_0_final_directive.md
Normal file
297
.agent/workflows/v1_0_final_directive.md
Normal file
@@ -0,0 +1,297 @@
|
||||
---
|
||||
description: Mrtva Dolina v1.0 - Final Director Directive
|
||||
---
|
||||
|
||||
# 🎬 MRTVA DOLINA v1.0 - ZADNJI DIREKTORSKI UKAZ
|
||||
|
||||
**STATUS**: ACTIVE
|
||||
**PRIORITY**: CRITICAL
|
||||
**TURBO**: // turbo-all
|
||||
**ASSIGNED**: Antigravity Agent (Autonomous Execution)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 MISSION OVERVIEW
|
||||
|
||||
Implement the final v1.0 systems for "Mrtva Dolina" (Death Valley / DolinaSmrti) with full autonomy. This is the capstone build that brings together political systems, automation, cinematic intro, and accessibility features.
|
||||
|
||||
---
|
||||
|
||||
## 📦 DELIVERABLES
|
||||
|
||||
### 1️⃣ POLITIČNI & PRAVNI SISTEM (Style 32)
|
||||
|
||||
#### 🏛️ ODVETNIK (Lawyer NPC)
|
||||
**Visual Assets Required:**
|
||||
- **Character**: Wrinkled suit, thick glasses (no pupils), brown briefcase
|
||||
- **Style**: Dark-Chibi Noir (Style 32)
|
||||
- **Function**: Handles divorces (50,000g fee), takes 25% of money, triggers town gossip
|
||||
|
||||
**Game Mechanics:**
|
||||
```javascript
|
||||
LawyerService {
|
||||
- divorceFee: 50000g
|
||||
- lawyerCut: 25%
|
||||
- triggerGossip: true
|
||||
- cooldown: 7 days
|
||||
}
|
||||
```
|
||||
|
||||
#### 🏛️ ŽUPAN (Mayor NPC)
|
||||
**Visual Assets Required:**
|
||||
- **Character**: Post-apocalyptic style with ceremonial sash
|
||||
- **Style**: Dark-Chibi Noir (Style 32)
|
||||
- **Function**: Issues biome permits, collects taxes
|
||||
|
||||
**Game Mechanics:**
|
||||
```javascript
|
||||
MayorService {
|
||||
- biomePermits: {
|
||||
desert: 10000g,
|
||||
mountains: 15000g,
|
||||
jungle: 20000g
|
||||
}
|
||||
- taxRate: 10%
|
||||
- taxInterval: 30 days
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ DELO & AVTOMATIZACIJA
|
||||
|
||||
#### 🎬 4-Frame Animation Cycles
|
||||
**Required Animations:**
|
||||
1. **Cow Milking** (`milking_cycle_4f.png`)
|
||||
- Frame 1: Approach bucket
|
||||
- Frame 2: Position hands
|
||||
- Frame 3: Squeeze motion
|
||||
- Frame 4: Milk stream visible
|
||||
|
||||
2. **Blacksmithing** (`blacksmith_cycle_4f.png`)
|
||||
- Frame 1: Lift hammer
|
||||
- Frame 2: Swing down
|
||||
- Frame 3: Impact + sparks ✨
|
||||
- Frame 4: Return to lift
|
||||
|
||||
3. **Chopping Wood** (`chop_wood_cycle_4f.png`)
|
||||
- Frame 1: Raise axe
|
||||
- Frame 2: Swing arc
|
||||
- Frame 3: Impact + wood chips
|
||||
- Frame 4: Pull axe out
|
||||
|
||||
4. **Mining** (`mining_cycle_4f.png`)
|
||||
- Frame 1: Pickaxe raised
|
||||
- Frame 2: Swing motion
|
||||
- Frame 3: Impact + rock debris
|
||||
- Frame 4: Reset stance
|
||||
|
||||
#### 🧟 Zombie Workers (24/7 Automation)
|
||||
**Visual Requirements:**
|
||||
- Purple glowing eyes (violet: `#9D4EDD`)
|
||||
- Style 32 Dark-Chibi aesthetic
|
||||
- Carrying animations with resources
|
||||
|
||||
**Mechanics:**
|
||||
```javascript
|
||||
ZombieWorker {
|
||||
- workHours: 24/7
|
||||
- eyeColor: "#9D4EDD" (purple)
|
||||
- autoStorage: true
|
||||
- efficiency: 75%
|
||||
- maintenanceCost: 50g/day
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ FILMSKI INTRO & VOICE CLONING
|
||||
|
||||
#### 🎥 Cinematic Intro Sequence
|
||||
**Technical Requirements:**
|
||||
1. **Ken Burns Effect**: Slow zoom + pan on still images
|
||||
2. **Cross-Fade Transitions**: 1.5s fade between scenes
|
||||
3. **Typewriter Text**: Natural typing effect (60ms/char)
|
||||
4. **Blur-to-Clear Transition**: Final scene transition into gameplay
|
||||
|
||||
**Voice Cloning:**
|
||||
- **Source**: User's Slovenian voice (male)
|
||||
- **Process**: Clone for multi-language narration
|
||||
- **Effect**: Radio filter for post-apocalyptic aesthetic
|
||||
- **Languages**: Slovenian (original), English, German, Italian, Chinese
|
||||
|
||||
**Intro Script Structure:**
|
||||
```
|
||||
SCENE 1: Abandoned farm (Ken Burns zoom)
|
||||
"Leta 2084, Dolina se ni več obranila..."
|
||||
|
||||
SCENE 2: Laboratory flash
|
||||
"Incident je pustil posledice, ki jih nihče ni pričakoval..."
|
||||
|
||||
SCENE 3: Kai standing in field (blur-to-clear)
|
||||
"Zdaj je čas, da stvari spravimo nazaj v red."
|
||||
|
||||
TRANSITION: Blur-to-gameplay (Base Farm)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ PREGLEDNOST & DOSTOPNOST
|
||||
|
||||
#### 🖼️ Asset Gallery (Thumbnail Grid)
|
||||
**Implementation:**
|
||||
- Create `asset_gallery.html` in `/tools/`
|
||||
- Grid layout: 4 columns, auto rows
|
||||
- Thumbnail size: 128x128px
|
||||
- Categories: Buildings, NPCs, Terrain, Props, UI, Interior, Weapons, Tools
|
||||
- Live search filter
|
||||
- Click to enlarge (modal)
|
||||
|
||||
**Features:**
|
||||
```html
|
||||
- Live thumbnail grid of all PNG assets
|
||||
- Hover to show filename
|
||||
- Click to view full size
|
||||
- Filter by category
|
||||
- Sort by date/name/size
|
||||
```
|
||||
|
||||
#### 🔍 Hover Preview System
|
||||
**IDE Integration:**
|
||||
- When hovering over `.png` filename in code → show preview popup
|
||||
- Preview size: 256x256px max
|
||||
- Fade-in: 200ms
|
||||
- Shows: filename, dimensions, file size
|
||||
|
||||
#### 🎨 ADHD Focus Mode
|
||||
**Features:**
|
||||
```javascript
|
||||
ADHDFocusMode {
|
||||
- reduceAnimations: true
|
||||
- highlightInteractables: true
|
||||
- simplifyUI: true
|
||||
- increaseContrast: 150%
|
||||
- reduceCognitiveLoad: true
|
||||
}
|
||||
```
|
||||
|
||||
#### 🌈 Color Blindness Filters
|
||||
**Modes:**
|
||||
- Protanopia (red-blind)
|
||||
- Deuteranopia (green-blind)
|
||||
- Tritanopia (blue-blind)
|
||||
- Monochrome mode
|
||||
|
||||
#### 📂 Smart Auto-Labeling & Organization
|
||||
**Naming Convention:**
|
||||
```
|
||||
{character}_{action}_{style}.png
|
||||
Examples:
|
||||
- gronk_vape_style32.png
|
||||
- kai_idle_style32.png
|
||||
- ana_diary_style32.png
|
||||
```
|
||||
|
||||
**Folder Structure:**
|
||||
```
|
||||
/assets/images/STYLE_32_SESSION_JAN_04/
|
||||
├── characters/
|
||||
│ ├── gronk/
|
||||
│ ├── kai/
|
||||
│ ├── ana/
|
||||
│ └── zombies/
|
||||
├── biomes/
|
||||
│ ├── desert/
|
||||
│ ├── mountains/
|
||||
│ └── jungle/
|
||||
├── buildings/
|
||||
├── props/
|
||||
├── ui/
|
||||
└── effects/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 EXECUTION SEQUENCE
|
||||
|
||||
### Phase 1: Asset Generation (Style 32)
|
||||
```bash
|
||||
1. Generate lawyer_character_style32.png
|
||||
2. Generate mayor_character_style32.png
|
||||
3. Generate 4-frame animation spritesheets
|
||||
4. Generate zombie_worker_purple_eyes_style32.png
|
||||
```
|
||||
|
||||
### Phase 2: Game Systems Implementation
|
||||
```bash
|
||||
1. Create LawyerService.js
|
||||
2. Create MayorService.js
|
||||
3. Create ZombieWorkerManager.js
|
||||
4. Create WorkAnimationSystem.js
|
||||
```
|
||||
|
||||
### Phase 3: Cinematic Intro
|
||||
```bash
|
||||
1. Create IntroScene.js with Ken Burns
|
||||
2. Implement voice cloning pipeline
|
||||
3. Add typewriter text effect
|
||||
4. Implement blur-to-clear transition
|
||||
```
|
||||
|
||||
### Phase 4: Accessibility & Gallery
|
||||
```bash
|
||||
1. Create asset_gallery.html
|
||||
2. Implement hover preview system
|
||||
3. Add ADHD Focus Mode toggle
|
||||
4. Implement colorblind filters
|
||||
5. Reorganize assets into smart folders
|
||||
```
|
||||
|
||||
### Phase 5: Testing & Polish
|
||||
```bash
|
||||
1. Test all new systems in-game
|
||||
2. Verify accessibility features
|
||||
3. Test intro sequence
|
||||
4. Final QA pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 SUCCESS METRICS
|
||||
|
||||
- ✅ All Style 32 political NPCs generated
|
||||
- ✅ 4 animation cycles (4 frames each) complete
|
||||
- ✅ Zombie workers functional with purple eyes
|
||||
- ✅ Intro plays smoothly with Ken Burns + typewriter
|
||||
- ✅ Asset gallery shows all 342+ images
|
||||
- ✅ Hover preview works in code editor
|
||||
- ✅ ADHD mode reduces cognitive load
|
||||
- ✅ All colorblind filters functional
|
||||
- ✅ Assets organized in smart folder structure
|
||||
|
||||
---
|
||||
|
||||
## 🎯 FINAL COMMIT MESSAGE
|
||||
|
||||
```
|
||||
feat(v1.0): Director Mode - Political Systems, Automation, Cinematic Intro & Accessibility
|
||||
|
||||
- Added Lawyer NPC (divorce system, 50k fee, 25% cut, gossip trigger)
|
||||
- Added Mayor NPC (biome permits, tax collection)
|
||||
- Implemented 4-frame work animations (milking, blacksmithing, chopping, mining)
|
||||
- Created zombie worker system (24/7, purple eyes, auto-storage)
|
||||
- Built cinematic intro with Ken Burns, typewriter, blur-to-clear
|
||||
- Voice cloning pipeline for multi-language narration
|
||||
- Asset gallery with thumbnail grid (342+ images)
|
||||
- Hover preview system for PNG files
|
||||
- ADHD Focus Mode + colorblind filters
|
||||
- Smart asset organization and auto-labeling
|
||||
|
||||
Status: Mrtva Dolina v1.0 COMPLETE 🎬
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**END OF DIRECTIVE**
|
||||
**Agent: Proceed with autonomous execution.**
|
||||
**No further approval required - DIRECTOR MODE ACTIVE.**
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 525 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 444 KiB |
829
docs/V1_0_IMPLEMENTATION_PLAN.md
Normal file
829
docs/V1_0_IMPLEMENTATION_PLAN.md
Normal file
@@ -0,0 +1,829 @@
|
||||
# 🎯 MRTVA DOLINA v1.0 - IMPLEMENTATION PLAN
|
||||
|
||||
**Generated**: 2026-01-04 18:52 CET
|
||||
**Mode**: DIRECTOR MODE (Autonomous)
|
||||
**Target**: v1.0 Release Build
|
||||
**Status**: 🟢 READY TO EXECUTE
|
||||
|
||||
---
|
||||
|
||||
## 📅 TIMELINE
|
||||
|
||||
**Total Estimated Time**: 6-8 hours
|
||||
**Phases**: 5
|
||||
**Autonomous**: YES (// turbo-all)
|
||||
|
||||
---
|
||||
|
||||
## 🔢 PHASE 1: ASSET GENERATION (Style 32)
|
||||
**Duration**: 2 hours
|
||||
**Priority**: HIGH
|
||||
|
||||
### Tasks:
|
||||
|
||||
#### 1.1 Political NPCs
|
||||
- [ ] `lawyer_wrinkled_suit_style32.png` - Odvetnik z aktovko in debelimi očali
|
||||
- [ ] `mayor_post_apo_sash_style32.png` - Župan z lento, post-apo stil
|
||||
|
||||
#### 1.2 Animation Spritesheets (4 frames each)
|
||||
- [ ] `milking_cow_4frame_style32.png` - Molža krave
|
||||
- [ ] `blacksmithing_4frame_style32.png` - Kovaštvo z iskrami
|
||||
- [ ] `chopping_wood_4frame_style32.png` - Sekanje drv
|
||||
- [ ] `mining_4frame_style32.png` - Rudarjenje
|
||||
|
||||
#### 1.3 Zombie Workers
|
||||
- [ ] `zombie_worker_purple_eyes_style32.png` - Zombie delavec z vijolično očmi
|
||||
- [ ] `zombie_worker_carrying_style32.png` - Zombie nosi material
|
||||
- [ ] `zombie_worker_mining_style32.png` - Zombie rudari
|
||||
|
||||
**Output Location**: `/assets/images/STYLE_32_SESSION_JAN_04/`
|
||||
|
||||
---
|
||||
|
||||
## 🎮 PHASE 2: GAME SYSTEMS IMPLEMENTATION
|
||||
**Duration**: 2 hours
|
||||
**Priority**: HIGH
|
||||
|
||||
### Tasks:
|
||||
|
||||
#### 2.1 Lawyer Service System
|
||||
**File**: `/src/systems/LawyerService.js`
|
||||
|
||||
```javascript
|
||||
export class LawyerService {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.divorceFee = 50000;
|
||||
this.lawyerCut = 0.25; // 25%
|
||||
this.cooldownDays = 7;
|
||||
this.lastDivorce = null;
|
||||
}
|
||||
|
||||
processDivorce(player, partner) {
|
||||
if (player.gold < this.divorceFee) {
|
||||
return { success: false, reason: 'insufficient_funds' };
|
||||
}
|
||||
|
||||
const lawyerCut = this.divorceFee * this.lawyerCut;
|
||||
player.gold -= this.divorceFee;
|
||||
this.scene.economy.lawyerGold += lawyerCut;
|
||||
|
||||
// Trigger town gossip
|
||||
this.scene.gossipSystem.spread({
|
||||
type: 'divorce',
|
||||
source: player.name,
|
||||
partner: partner.name,
|
||||
severity: 'high'
|
||||
});
|
||||
|
||||
this.lastDivorce = this.scene.time.getCurrentDay();
|
||||
return { success: true, fee: this.divorceFee, lawyerCut };
|
||||
}
|
||||
|
||||
canProcess() {
|
||||
if (!this.lastDivorce) return true;
|
||||
const daysSince = this.scene.time.getCurrentDay() - this.lastDivorce;
|
||||
return daysSince >= this.cooldownDays;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Mayor Service System
|
||||
**File**: `/src/systems/MayorService.js`
|
||||
|
||||
```javascript
|
||||
export class MayorService {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.biomePermits = {
|
||||
desert: 10000,
|
||||
mountains: 15000,
|
||||
jungle: 20000,
|
||||
swamp: 12000,
|
||||
arctic: 18000
|
||||
};
|
||||
this.taxRate = 0.10; // 10%
|
||||
this.taxInterval = 30; // days
|
||||
this.lastTaxCollection = 0;
|
||||
}
|
||||
|
||||
issuePermit(player, biome) {
|
||||
const cost = this.biomePermits[biome];
|
||||
if (!cost) return { success: false, reason: 'invalid_biome' };
|
||||
if (player.gold < cost) return { success: false, reason: 'insufficient_funds' };
|
||||
|
||||
player.gold -= cost;
|
||||
player.biomeAccess[biome] = true;
|
||||
this.scene.economy.mayorGold += cost;
|
||||
|
||||
return { success: true, biome, cost };
|
||||
}
|
||||
|
||||
collectTax(player) {
|
||||
const daysSince = this.scene.time.getCurrentDay() - this.lastTaxCollection;
|
||||
if (daysSince < this.taxInterval) return { success: false, reason: 'too_soon' };
|
||||
|
||||
const taxAmount = Math.floor(player.gold * this.taxRate);
|
||||
player.gold -= taxAmount;
|
||||
this.scene.economy.mayorGold += taxAmount;
|
||||
this.lastTaxCollection = this.scene.time.getCurrentDay();
|
||||
|
||||
return { success: true, amount: taxAmount };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 Zombie Worker Manager
|
||||
**File**: `/src/systems/ZombieWorkerManager.js`
|
||||
|
||||
```javascript
|
||||
export class ZombieWorkerManager {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.workers = [];
|
||||
this.efficiency = 0.75; // 75% of human speed
|
||||
this.maintenanceCostPerDay = 50;
|
||||
}
|
||||
|
||||
assignTask(zombie, task) {
|
||||
zombie.currentTask = task;
|
||||
zombie.workProgress = 0;
|
||||
zombie.isWorking = true;
|
||||
|
||||
// Purple eye glow effect
|
||||
zombie.eyes.setTint(0x9D4EDD); // violet
|
||||
zombie.eyes.alpha = 0.8;
|
||||
}
|
||||
|
||||
update(delta) {
|
||||
this.workers.forEach(zombie => {
|
||||
if (!zombie.isWorking) return;
|
||||
|
||||
const task = zombie.currentTask;
|
||||
const progressRate = (this.efficiency * delta) / 1000;
|
||||
zombie.workProgress += progressRate;
|
||||
|
||||
if (zombie.workProgress >= task.duration) {
|
||||
this.completeTask(zombie, task);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
completeTask(zombie, task) {
|
||||
// Auto-store resources in base storage
|
||||
this.scene.storage.add(task.resource, task.amount);
|
||||
zombie.isWorking = false;
|
||||
zombie.currentTask = null;
|
||||
|
||||
// Find next task
|
||||
const nextTask = this.scene.taskQueue.getNext();
|
||||
if (nextTask) {
|
||||
this.assignTask(zombie, nextTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.4 Work Animation System
|
||||
**File**: `/src/systems/WorkAnimationSystem.js`
|
||||
|
||||
```javascript
|
||||
export class WorkAnimationSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.animations = {};
|
||||
}
|
||||
|
||||
create() {
|
||||
// Milking animation
|
||||
this.scene.anims.create({
|
||||
key: 'milking',
|
||||
frames: this.scene.anims.generateFrameNumbers('milking_4frame', { start: 0, end: 3 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Blacksmithing with sparks
|
||||
this.scene.anims.create({
|
||||
key: 'blacksmithing',
|
||||
frames: this.scene.anims.generateFrameNumbers('blacksmith_4frame', { start: 0, end: 3 }),
|
||||
frameRate: 6,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Chopping wood
|
||||
this.scene.anims.create({
|
||||
key: 'chopping',
|
||||
frames: this.scene.anims.generateFrameNumbers('chop_wood_4frame', { start: 0, end: 3 }),
|
||||
frameRate: 7,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Mining
|
||||
this.scene.anims.create({
|
||||
key: 'mining',
|
||||
frames: this.scene.anims.generateFrameNumbers('mining_4frame', { start: 0, end: 3 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
|
||||
playAnimation(sprite, animKey) {
|
||||
sprite.play(animKey);
|
||||
|
||||
// Add particle effects for specific frames
|
||||
if (animKey === 'blacksmithing') {
|
||||
sprite.on('animationupdate', (anim, frame) => {
|
||||
if (frame.index === 2) { // Impact frame
|
||||
this.scene.particles.emitSparks(sprite.x, sprite.y);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎬 PHASE 3: CINEMATIC INTRO SYSTEM
|
||||
**Duration**: 2 hours
|
||||
**Priority**: MEDIUM
|
||||
|
||||
### Tasks:
|
||||
|
||||
#### 3.1 Intro Scene with Ken Burns Effect
|
||||
**File**: `/src/scenes/IntroScene.js`
|
||||
|
||||
```javascript
|
||||
export class IntroScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'IntroScene' });
|
||||
}
|
||||
|
||||
create() {
|
||||
this.cameras.main.setBackgroundColor('#000000');
|
||||
|
||||
// Scene 1: Abandoned farm with Ken Burns zoom
|
||||
this.showScene1();
|
||||
}
|
||||
|
||||
showScene1() {
|
||||
const bg = this.add.image(0, 0, 'intro_farm_abandoned').setOrigin(0);
|
||||
bg.setScale(1.2); // Start zoomed in
|
||||
|
||||
// Ken Burns: slow zoom out + pan
|
||||
this.tweens.add({
|
||||
targets: bg,
|
||||
scale: 1.0,
|
||||
x: -50,
|
||||
y: -30,
|
||||
duration: 5000,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
// Typewriter text
|
||||
this.showTypewriter(
|
||||
"Leta 2084, Dolina se ni več obranila...",
|
||||
100, 500,
|
||||
() => this.crossFadeToScene2()
|
||||
);
|
||||
}
|
||||
|
||||
showTypewriter(text, x, y, onComplete) {
|
||||
const textObj = this.add.text(x, y, '', {
|
||||
fontSize: '24px',
|
||||
fontFamily: 'Georgia',
|
||||
color: '#FFFFFF',
|
||||
stroke: '#000000',
|
||||
strokeThickness: 4
|
||||
});
|
||||
|
||||
let charIndex = 0;
|
||||
const typeSpeed = 60; // ms per character
|
||||
|
||||
const timer = this.time.addEvent({
|
||||
delay: typeSpeed,
|
||||
repeat: text.length - 1,
|
||||
callback: () => {
|
||||
textObj.text += text[charIndex];
|
||||
charIndex++;
|
||||
if (charIndex === text.length && onComplete) {
|
||||
this.time.delayedCall(2000, onComplete);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
crossFadeToScene2() {
|
||||
this.cameras.main.fadeOut(1500, 0, 0, 0);
|
||||
this.cameras.main.once('camerafadeoutcomplete', () => {
|
||||
this.showScene2();
|
||||
this.cameras.main.fadeIn(1500, 0, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
showScene2() {
|
||||
this.children.removeAll();
|
||||
const bg = this.add.image(400, 300, 'intro_lab_flash').setScale(1.0);
|
||||
|
||||
this.showTypewriter(
|
||||
"Incident je pustil posledice, ki jih nihče ni pričakoval...",
|
||||
100, 500,
|
||||
() => this.blurToGameplay()
|
||||
);
|
||||
}
|
||||
|
||||
blurToGameplay() {
|
||||
// Blur-to-clear transition
|
||||
const blur = this.cameras.main.postFX.addBlur(0, 2, 2, 10);
|
||||
|
||||
this.cameras.main.fadeOut(2000, 0, 0, 0);
|
||||
|
||||
this.tweens.add({
|
||||
targets: blur,
|
||||
strength: 0,
|
||||
duration: 2000,
|
||||
onComplete: () => {
|
||||
this.scene.start('GameScene'); // Start gameplay
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 Voice Cloning Pipeline
|
||||
**File**: `/tools/voice_clone.py`
|
||||
|
||||
```python
|
||||
import edge_tts
|
||||
import asyncio
|
||||
from pydub import AudioSegment
|
||||
from pydub.effects import low_pass_filter, high_pass_filter
|
||||
|
||||
async def clone_voice_with_radio_filter(text, lang='sl', output_path='narration.mp3'):
|
||||
"""
|
||||
Clone user's voice and apply radio filter
|
||||
"""
|
||||
# Use Edge TTS for voice generation
|
||||
communicate = edge_tts.Communicate(text, voice=f"{lang}-SL-PetraNeural")
|
||||
await communicate.save(output_path)
|
||||
|
||||
# Apply radio filter (post-apocalyptic aesthetic)
|
||||
audio = AudioSegment.from_file(output_path)
|
||||
|
||||
# Radio effect: bandpass filter + compression
|
||||
radio_audio = high_pass_filter(audio, 300) # Cut below 300Hz
|
||||
radio_audio = low_pass_filter(radio_audio, 3000) # Cut above 3kHz
|
||||
radio_audio = radio_audio + 3 # Increase volume slightly
|
||||
|
||||
radio_audio.export(output_path, format="mp3")
|
||||
print(f"✅ Voice generated with radio filter: {output_path}")
|
||||
|
||||
# Generate all languages
|
||||
languages = {
|
||||
'sl': 'sl-SL-PetraNeural', # Slovenian (use as base)
|
||||
'en': 'en-US-GuyNeural', # English
|
||||
'de': 'de-DE-ConradNeural', # German
|
||||
'it': 'it-IT-DiegoNeural', # Italian
|
||||
'zh': 'zh-CN-YunxiNeural' # Chinese
|
||||
}
|
||||
|
||||
async def generate_all_narrations():
|
||||
script = "Leta 2084, Dolina se ni več obranila..."
|
||||
|
||||
for lang_code, voice in languages.items():
|
||||
await clone_voice_with_radio_filter(
|
||||
script,
|
||||
lang_code,
|
||||
f"assets/audio/intro_{lang_code}.mp3"
|
||||
)
|
||||
|
||||
asyncio.run(generate_all_narrations())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ PHASE 4: ACCESSIBILITY & ASSET GALLERY
|
||||
**Duration**: 1.5 hours
|
||||
**Priority**: MEDIUM
|
||||
|
||||
### Tasks:
|
||||
|
||||
#### 4.1 Asset Gallery (Thumbnail Grid)
|
||||
**File**: `/tools/asset_gallery.html`
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>DolinaSmrti Asset Gallery</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: #1a1a1a;
|
||||
color: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #9D4EDD;
|
||||
}
|
||||
.search-bar {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin: 0 auto 30px;
|
||||
display: block;
|
||||
padding: 12px;
|
||||
font-size: 16px;
|
||||
border: 2px solid #9D4EDD;
|
||||
border-radius: 8px;
|
||||
background: #2a2a2a;
|
||||
color: #fff;
|
||||
}
|
||||
.filter-buttons {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.filter-btn {
|
||||
padding: 8px 16px;
|
||||
margin: 5px;
|
||||
border: 2px solid #9D4EDD;
|
||||
background: #2a2a2a;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.filter-btn:hover, .filter-btn.active {
|
||||
background: #9D4EDD;
|
||||
color: #000;
|
||||
}
|
||||
.gallery-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
.asset-card {
|
||||
background: #2a2a2a;
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.asset-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 16px rgba(157, 78, 221, 0.4);
|
||||
}
|
||||
.asset-card img {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
background: #1a1a1a;
|
||||
}
|
||||
.asset-card .filename {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #aaa;
|
||||
word-break: break-all;
|
||||
}
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.9);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.modal.active { display: flex; }
|
||||
.modal img {
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
border-radius: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎨 DolinaSmrti Asset Gallery</h1>
|
||||
<input type="text" class="search-bar" id="search" placeholder="Search assets...">
|
||||
|
||||
<div class="filter-buttons">
|
||||
<button class="filter-btn active" data-filter="all">All (342)</button>
|
||||
<button class="filter-btn" data-filter="buildings">Buildings</button>
|
||||
<button class="filter-btn" data-filter="npcs">NPCs</button>
|
||||
<button class="filter-btn" data-filter="terrain">Terrain</button>
|
||||
<button class="filter-btn" data-filter="interior">Interior</button>
|
||||
<button class="filter-btn" data-filter="weapons">Weapons</button>
|
||||
<button class="filter-btn" data-filter="tools">Tools</button>
|
||||
<button class="filter-btn" data-filter="ui">UI</button>
|
||||
</div>
|
||||
|
||||
<div class="gallery-grid" id="gallery"></div>
|
||||
|
||||
<div class="modal" id="modal">
|
||||
<img id="modal-img" src="" alt="">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const assetPath = '../assets/images/STYLE_32_SESSION_JAN_04/';
|
||||
const gallery = document.getElementById('gallery');
|
||||
const modal = document.getElementById('modal');
|
||||
const modalImg = document.getElementById('modal-img');
|
||||
const search = document.getElementById('search');
|
||||
|
||||
let assets = [];
|
||||
|
||||
// Load assets from directory
|
||||
fetch(assetPath)
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const links = [...doc.querySelectorAll('a')];
|
||||
|
||||
assets = links
|
||||
.filter(a => a.href.endsWith('.png'))
|
||||
.map(a => ({
|
||||
name: a.textContent,
|
||||
path: assetPath + a.textContent,
|
||||
category: detectCategory(a.textContent)
|
||||
}));
|
||||
|
||||
renderGallery(assets);
|
||||
});
|
||||
|
||||
function detectCategory(filename) {
|
||||
if (filename.match(/^(barn|bakery|church|house|farmhouse|tavern|windmill)/i)) return 'buildings';
|
||||
if (filename.match(/^npc/i)) return 'npcs';
|
||||
if (filename.match(/^terrain/i)) return 'terrain';
|
||||
if (filename.match(/^interior/i)) return 'interior';
|
||||
if (filename.match(/weapon/i)) return 'weapons';
|
||||
if (filename.match(/tool/i)) return 'tools';
|
||||
if (filename.match(/(button|icon|bar|panel)/i)) return 'ui';
|
||||
return 'misc';
|
||||
}
|
||||
|
||||
function renderGallery(items) {
|
||||
gallery.innerHTML = items.map(asset => `
|
||||
<div class="asset-card" data-category="${asset.category}" onclick="openModal('${asset.path}')">
|
||||
<img src="${asset.path}" alt="${asset.name}" loading="lazy">
|
||||
<div class="filename">${asset.name}</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function openModal(src) {
|
||||
modalImg.src = src;
|
||||
modal.classList.add('active');
|
||||
}
|
||||
|
||||
modal.addEventListener('click', () => modal.classList.remove('active'));
|
||||
|
||||
// Filter buttons
|
||||
document.querySelectorAll('.filter-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
|
||||
const filter = btn.dataset.filter;
|
||||
const cards = document.querySelectorAll('.asset-card');
|
||||
|
||||
cards.forEach(card => {
|
||||
if (filter === 'all' || card.dataset.category === filter) {
|
||||
card.style.display = 'block';
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Search
|
||||
search.addEventListener('input', (e) => {
|
||||
const query = e.target.value.toLowerCase();
|
||||
const filtered = assets.filter(a => a.name.toLowerCase().includes(query));
|
||||
renderGallery(filtered);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
#### 4.2 ADHD Focus Mode
|
||||
**File**: `/src/systems/AccessibilityManager.js`
|
||||
|
||||
```javascript
|
||||
export class AccessibilityManager {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.adhdMode = false;
|
||||
this.colorblindMode = null;
|
||||
}
|
||||
|
||||
enableADHDMode() {
|
||||
this.adhdMode = true;
|
||||
|
||||
// Reduce animations
|
||||
this.scene.tweens.timeScale = 0.7; // Slower, more predictable
|
||||
|
||||
// Highlight interactables
|
||||
this.scene.interactables.forEach(obj => {
|
||||
obj.setStrokeStyle(4, 0xFFFF00, 1); // Yellow outline
|
||||
});
|
||||
|
||||
// Simplify UI
|
||||
this.scene.ui.setAlpha(0.9);
|
||||
this.scene.ui.setScale(1.1); // Slightly larger
|
||||
|
||||
// Increase contrast
|
||||
this.scene.cameras.main.setAlpha(1.5);
|
||||
|
||||
console.log('✅ ADHD Focus Mode enabled');
|
||||
}
|
||||
|
||||
setColorblindFilter(type) {
|
||||
this.colorblindMode = type;
|
||||
const filters = {
|
||||
protanopia: { r: 0.56667, g: 0.43333, b: 0 },
|
||||
deuteranopia: { r: 0.625, g: 0.375, b: 0 },
|
||||
tritanopia: { r: 0.95, g: 0.05, b: 0 },
|
||||
monochrome: { r: 0.299, g: 0.587, b: 0.114 }
|
||||
};
|
||||
|
||||
if (filters[type]) {
|
||||
this.scene.cameras.main.setTint(Phaser.Display.Color.GetColor(
|
||||
filters[type].r * 255,
|
||||
filters[type].g * 255,
|
||||
filters[type].b * 255
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3 Smart Asset Organization Script
|
||||
**File**: `/scripts/organize_assets.py`
|
||||
|
||||
```python
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
SOURCE_DIR = "assets/images/STYLE_32_SESSION_JAN_04"
|
||||
TARGET_STRUCTURE = {
|
||||
"characters": {
|
||||
"gronk": ["gronk"],
|
||||
"kai": ["kai"],
|
||||
"ana": ["ana"],
|
||||
"zombies": ["zombie"]
|
||||
},
|
||||
"buildings": ["barn", "bakery", "church", "farmhouse", "house", "tavern", "windmill", "workshop"],
|
||||
"biomes": {
|
||||
"desert": ["desert"],
|
||||
"mountains": ["mountain"],
|
||||
"jungle": ["jungle"],
|
||||
"swamp": ["swamp"]
|
||||
},
|
||||
"props": ["barrel", "chest", "campfire", "crate", "grave"],
|
||||
"ui": ["button", "icon", "bar", "panel", "slot"],
|
||||
"interior": ["interior"],
|
||||
"weapons": ["weapon"],
|
||||
"tools": ["tool"],
|
||||
"terrain": ["terrain"]
|
||||
}
|
||||
|
||||
def organize_assets():
|
||||
"""Reorganize assets into smart folder structure"""
|
||||
for category, patterns in TARGET_STRUCTURE.items():
|
||||
if isinstance(patterns, dict):
|
||||
# Nested structure
|
||||
for subfolder, subpatterns in patterns.items():
|
||||
organize_category(category, subfolder, subpatterns)
|
||||
else:
|
||||
organize_category(category, None, patterns)
|
||||
|
||||
def organize_category(category, subfolder, patterns):
|
||||
target_path = Path(SOURCE_DIR) / category
|
||||
if subfolder:
|
||||
target_path = target_path / subfolder
|
||||
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for file in Path(SOURCE_DIR).glob("*.png"):
|
||||
filename = file.name.lower()
|
||||
if any(pattern in filename for pattern in patterns):
|
||||
new_path = target_path / file.name
|
||||
shutil.copy(file, new_path)
|
||||
print(f"✅ {file.name} → {category}/{subfolder or ''}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
organize_assets()
|
||||
print("🎉 Asset organization complete!")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ PHASE 5: TESTING & FINAL COMMIT
|
||||
**Duration**: 0.5 hours
|
||||
**Priority**: CRITICAL
|
||||
|
||||
### Tasks:
|
||||
|
||||
- [ ] Test lawyer service (divorce flow, gossip trigger, gold calculation)
|
||||
- [ ] Test mayor service (permit purchase, tax collection)
|
||||
- [ ] Test zombie workers (assignment, purple eyes, auto-storage)
|
||||
- [ ] Test work animations (all 4 cycles, particle effects)
|
||||
- [ ] Test intro sequence (Ken Burns, typewriter, blur-to-clear)
|
||||
- [ ] Test asset gallery (thumbnail grid, search, filters, modal)
|
||||
- [ ] Test ADHD mode (reduced animations, highlighted interactables)
|
||||
- [ ] Test colorblind filters (all 4 modes)
|
||||
- [ ] Verify asset organization (smart folders created correctly)
|
||||
|
||||
### Final Commit:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat(v1.0): Director Mode - Complete Political, Automation, Cinematic & Accessibility Systems
|
||||
|
||||
SYSTEMS IMPLEMENTED:
|
||||
✅ Lawyer NPC (divorce 50k, 25% cut, gossip)
|
||||
✅ Mayor NPC (biome permits, tax collection)
|
||||
✅ Zombie Workers (24/7, purple eyes, auto-storage)
|
||||
✅ Work Animations (milking, blacksmithing, chopping, mining)
|
||||
✅ Cinematic Intro (Ken Burns, typewriter, blur-to-clear)
|
||||
✅ Voice Cloning (multi-language, radio filter)
|
||||
✅ Asset Gallery (342+ thumbnails, search, filters)
|
||||
✅ ADHD Focus Mode (reduced animations, highlighted UI)
|
||||
✅ Colorblind Filters (protanopia, deuteranopia, tritanopia, monochrome)
|
||||
✅ Smart Asset Organization (characters, biomes, buildings, props)
|
||||
|
||||
STATUS: Mrtva Dolina v1.0 COMPLETE 🎬
|
||||
Assets: 342 images, 170MB
|
||||
Code: ~2000 new lines
|
||||
Systems: 9 new + 4 enhanced"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 DELIVERABLES SUMMARY
|
||||
|
||||
### Assets Generated: ~15
|
||||
- 2 political NPCs (lawyer, mayor)
|
||||
- 4 animation spritesheets (4 frames each = 16 frames)
|
||||
- 3 zombie worker variants
|
||||
|
||||
### Code Written: ~2000 lines
|
||||
- LawyerService.js (150 lines)
|
||||
- MayorService.js (120 lines)
|
||||
- ZombieWorkerManager.js (180 lines)
|
||||
- WorkAnimationSystem.js (140 lines)
|
||||
- IntroScene.js (200 lines)
|
||||
- AccessibilityManager.js (100 lines)
|
||||
- asset_gallery.html (250 lines)
|
||||
- voice_clone.py (80 lines)
|
||||
- organize_assets.py (60 lines)
|
||||
|
||||
### Systems Implemented: 9
|
||||
1. Lawyer Service
|
||||
2. Mayor Service
|
||||
3. Zombie Worker Manager
|
||||
4. Work Animation System
|
||||
5. Cinematic Intro Scene
|
||||
6. Voice Cloning Pipeline
|
||||
7. Asset Gallery
|
||||
8. ADHD Focus Mode
|
||||
9. Colorblind Filters
|
||||
|
||||
---
|
||||
|
||||
## 🎯 SUCCESS CRITERIA
|
||||
|
||||
✅ All political NPCs rendered and functional
|
||||
✅ Work animations smooth and particle effects working
|
||||
✅ Zombie workers operate 24/7 with purple eyes
|
||||
✅ Intro plays with Ken Burns, typewriter, and blur
|
||||
✅ Asset gallery shows all 342+ images with search
|
||||
✅ ADHD mode reduces cognitive load effectively
|
||||
✅ Colorblind filters functional for all 4 types
|
||||
✅ Assets organized in smart folder structure
|
||||
✅ All systems tested and bug-free
|
||||
✅ Commit message comprehensive and accurate
|
||||
|
||||
---
|
||||
|
||||
**EXECUTION MODE**: AUTONOMOUS (// turbo-all)
|
||||
**APPROVAL REQUIRED**: NO
|
||||
**PROCEED**: YES
|
||||
|
||||
---
|
||||
|
||||
**END OF IMPLEMENTATION PLAN**
|
||||
**Ready to execute on your command.**
|
||||
Reference in New Issue
Block a user