440 lines
11 KiB
Markdown
440 lines
11 KiB
Markdown
# 🌍 MULTI-LANGUAGE LOCALIZATION PLAN
|
||
**Game:** Mrtva Dolina / Death Valley
|
||
**Date:** January 4, 2026
|
||
**Status:** Planning Phase
|
||
|
||
---
|
||
|
||
## 📋 CORE LANGUAGES
|
||
|
||
### **Primary (DONE):** ✅
|
||
1. **Slovenian (sl-SI)** - Native language, COMPLETE
|
||
- ✅ All dialogue translated
|
||
- ✅ UI translated
|
||
- ✅ 12 prologue voiceovers (Rok + Petra)
|
||
- ✅ Real character portraits
|
||
|
||
### **Target Languages (TODO):**
|
||
2. **English (en-US)** 🇺🇸
|
||
3. **German (de-DE)** 🇩🇪
|
||
4. **Italian (it-IT)** 🇮🇹
|
||
5. **Croatian (hr-HR)** 🇭🇷
|
||
6. **Serbian (sr-RS)** 🇷🇸
|
||
|
||
---
|
||
|
||
## 🎯 IMPLEMENTATION STRATEGY
|
||
|
||
### **Phase 1: Localization System** (Week 1)
|
||
|
||
**Goal:** Create dynamic language switching system
|
||
|
||
**Tasks:**
|
||
1. ✅ Create `LocalizationSystem.js` (already exists!)
|
||
2. Create language JSON files:
|
||
- `assets/localization/en-US.json`
|
||
- `assets/localization/de-DE.json`
|
||
- `assets/localization/it-IT.json`
|
||
- `assets/localization/hr-HR.json`
|
||
- `assets/localization/sr-RS.json`
|
||
- `assets/localization/sl-SI.json` (extract current)
|
||
|
||
3. Update `PrologueScene.js` to use LocalizationSystem
|
||
4. Create language selector UI (main menu)
|
||
|
||
**Structure:**
|
||
```json
|
||
{
|
||
"ui": {
|
||
"skip": "Press ESC to skip",
|
||
"autoAdvance": "Press SPACE to toggle auto-advance"
|
||
},
|
||
"prologue": {
|
||
"scene_01": {
|
||
"speaker": "NARRATOR",
|
||
"text": "Year 2084. The zombie virus destroyed the world."
|
||
},
|
||
...
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### **Phase 2: Translation** (Week 2-3)
|
||
|
||
**Goal:** Translate all game text to 5 languages
|
||
|
||
**Content to Translate:**
|
||
|
||
**1. Prologue (12 scenes):**
|
||
- Scene descriptions
|
||
- Character dialogue
|
||
- Narrator text
|
||
|
||
**2. UI Elements:**
|
||
- Menu items
|
||
- Button labels
|
||
- Tutorial text
|
||
- Item descriptions
|
||
- Quest text
|
||
|
||
**3. NPC Dialogue:**
|
||
- Gronk conversations
|
||
- Town NPCs
|
||
- Quest givers
|
||
|
||
**Translation Methods:**
|
||
|
||
**Option A: Professional Translation** (BEST)
|
||
- Hire freelance translators (Fiverr, Upwork)
|
||
- ~$50-100 per language for game text
|
||
- Native speakers ensure quality
|
||
|
||
**Option B: AI Translation** (FAST)
|
||
- Use DeepL API (better than Google)
|
||
- Manual review by native speaker
|
||
- Free tier: 500,000 characters/month
|
||
|
||
**Option C: Community Translation** (FREE)
|
||
- Open GitHub for community contributions
|
||
- Steam forum volunteers
|
||
- Quality varies
|
||
|
||
**Recommendation:** Start with **DeepL + Manual Review**
|
||
|
||
---
|
||
|
||
### **Phase 3: Voiceover Generation** (Week 4-5)
|
||
|
||
**Goal:** Generate voiceovers for all 5 languages
|
||
|
||
**Available Voices (Microsoft Edge TTS):**
|
||
|
||
**English (en-US):**
|
||
- Male: `en-US-GuyNeural` (Kai)
|
||
- Female: `en-US-JennyNeural` (Ana)
|
||
- Narrator: `en-US-ChristopherNeural`
|
||
|
||
**German (de-DE):**
|
||
- Male: `de-DE-ConradNeural` (Kai)
|
||
- Female: `de-DE-KatjaNeural` (Ana)
|
||
- Narrator: `de-DE-KillianNeural`
|
||
|
||
**Italian (it-IT):**
|
||
- Male: `it-IT-DiegoNeural` (Kai)
|
||
- Female: `it-IT-ElsaNeural` (Ana)
|
||
- Narrator: `it-IT-GiuseppeNeural`
|
||
|
||
**Croatian (hr-HR):**
|
||
- Male: `hr-HR-SreckoNeural` (Kai)
|
||
- Female: `hr-HR-GabrijelaNeural` (Ana)
|
||
|
||
**Serbian (sr-RS):**
|
||
- Male: `sr-RS-NicholasNeural` (Kai)
|
||
- Female: `sr-RS-SophieNeural` (Ana)
|
||
|
||
**Generation Scripts:**
|
||
|
||
Create automated scripts for each language:
|
||
```bash
|
||
# ai_voice_gen/generate_prologue_english.sh
|
||
# ai_voice_gen/generate_prologue_german.sh
|
||
# ai_voice_gen/generate_prologue_italian.sh
|
||
# ai_voice_gen/generate_prologue_croatian.sh
|
||
# ai_voice_gen/generate_prologue_serbian.sh
|
||
```
|
||
|
||
**Folder Structure:**
|
||
```
|
||
assets/audio 🔴/voiceover/
|
||
├── prologue_sl/ (Slovenian - DONE)
|
||
├── prologue_en/ (English)
|
||
├── prologue_de/ (German)
|
||
├── prologue_it/ (Italian)
|
||
├── prologue_hr/ (Croatian)
|
||
└── prologue_sr/ (Serbian)
|
||
```
|
||
|
||
---
|
||
|
||
### **Phase 4: Integration** (Week 6)
|
||
|
||
**Goal:** Wire everything together
|
||
|
||
**Tasks:**
|
||
|
||
1. **Update PreloadScene:**
|
||
- Load language files
|
||
- Detect user's OS language (default)
|
||
- Load appropriate voiceover folder
|
||
|
||
2. **Language Selector UI:**
|
||
```
|
||
[MAIN MENU]
|
||
├── New Game
|
||
├── Continue
|
||
├── Options
|
||
│ └── Language ◄ NEW!
|
||
│ ├── 🇸🇮 Slovenščina
|
||
│ ├── 🇬🇧 English
|
||
│ ├── 🇩🇪 Deutsch
|
||
│ ├── 🇮🇹 Italiano
|
||
│ ├── 🇭🇷 Hrvatski
|
||
│ └── 🇷🇸 Srpski
|
||
└── Quit
|
||
```
|
||
|
||
3. **Dynamic Loading:**
|
||
```javascript
|
||
// PrologueScene.preload()
|
||
const lang = this.game.settings.language || 'sl-SI';
|
||
|
||
// Load appropriate audio
|
||
for (let i = 1; i <= 12; i++) {
|
||
const num = i.toString().padStart(2, '0');
|
||
this.load.audio(
|
||
`prologue_${num}`,
|
||
`assets/audio 🔴/voiceover/prologue_${lang.split('-')[0]}/prologue_${num}.wav`
|
||
);
|
||
}
|
||
|
||
// Load localization
|
||
this.load.json('localization', `assets/localization/${lang}.json`);
|
||
```
|
||
|
||
4. **Runtime Switching:**
|
||
- Save language preference to localStorage
|
||
- Reload scene when language changes
|
||
- Keep game state
|
||
|
||
---
|
||
|
||
## 📊 PRODUCTION TIMELINE
|
||
|
||
| Week | Task | Deliverable |
|
||
|------|------|-------------|
|
||
| **1** | Localization System | Language JSON structure |
|
||
| **2** | English Translation | en-US.json + voiceovers |
|
||
| **3** | German + Italian | de-DE.json, it-IT.json + voice |
|
||
| **4** | Croatian + Serbian | hr-HR.json, sr-RS.json + voice |
|
||
| **5** | Integration | Language selector UI |
|
||
| **6** | Testing | All languages verified |
|
||
|
||
**Total Time:** ~6 weeks (1.5 months)
|
||
|
||
---
|
||
|
||
## 💰 COST ESTIMATE
|
||
|
||
### **Option 1: Professional Translation**
|
||
- 5 languages × $75/language = **$375**
|
||
- Voiceovers: FREE (Edge TTS)
|
||
- **Total: $375**
|
||
|
||
### **Option 2: AI + Review**
|
||
- DeepL API: FREE (under limit)
|
||
- Native speaker review: $25/language × 5 = **$125**
|
||
- Voiceovers: FREE (Edge TTS)
|
||
- **Total: $125**
|
||
|
||
### **Option 3: DIY**
|
||
- Your time: ~40 hours
|
||
- Voiceovers: FREE (Edge TTS)
|
||
- **Total: $0** (time only)
|
||
|
||
**Recommendation:** **Option 2** (AI + Review) - Best balance of quality/cost/speed
|
||
|
||
---
|
||
|
||
## 🛠️ TECHNICAL IMPLEMENTATION
|
||
|
||
### **1. Create Localization Manager**
|
||
|
||
```javascript
|
||
// src/systems/LocalizationManager.js
|
||
class LocalizationManager {
|
||
constructor(game) {
|
||
this.game = game;
|
||
this.currentLanguage = 'sl-SI';
|
||
this.translations = {};
|
||
this.availableLanguages = [
|
||
{ code: 'sl-SI', name: 'Slovenščina', flag: '🇸🇮' },
|
||
{ code: 'en-US', name: 'English', flag: '🇬🇧' },
|
||
{ code: 'de-DE', name: 'Deutsch', flag: '🇩🇪' },
|
||
{ code: 'it-IT', name: 'Italiano', flag: '🇮🇹' },
|
||
{ code: 'hr-HR', name: 'Hrvatski', flag: '🇭🇷' },
|
||
{ code: 'sr-RS', name: 'Srpski', flag: '🇷🇸' }
|
||
];
|
||
}
|
||
|
||
loadLanguage(langCode) {
|
||
// Load JSON file
|
||
this.translations = this.game.cache.json.get(`lang_${langCode}`);
|
||
this.currentLanguage = langCode;
|
||
localStorage.setItem('game_language', langCode);
|
||
}
|
||
|
||
getText(key) {
|
||
const keys = key.split('.');
|
||
let value = this.translations;
|
||
for (const k of keys) {
|
||
value = value[k];
|
||
if (!value) return key; // Fallback
|
||
}
|
||
return value;
|
||
}
|
||
|
||
getVoiceFolder() {
|
||
const langShort = this.currentLanguage.split('-')[0];
|
||
return `prologue_${langShort}`;
|
||
}
|
||
}
|
||
```
|
||
|
||
### **2. Update PrologueScene**
|
||
|
||
```javascript
|
||
preload() {
|
||
// Detect language
|
||
const savedLang = localStorage.getItem('game_language') || 'sl-SI';
|
||
const langShort = savedLang.split('-')[0];
|
||
|
||
// Load localization
|
||
this.load.json(`lang_${savedLang}`, `assets/localization/${savedLang}.json`);
|
||
|
||
// Load character portraits
|
||
this.load.image('kai_portrait', 'reference_images/kai_master_style33.png');
|
||
this.load.image('ana_portrait', 'reference_images/ana_master_style33.png');
|
||
|
||
// Load voiceovers for current language
|
||
for (let i = 1; i <= 12; i++) {
|
||
const num = i.toString().padStart(2, '0');
|
||
this.load.audio(
|
||
`prologue_${num}`,
|
||
`assets/audio 🔴/voiceover/prologue_${langShort}/prologue_${num}.wav`
|
||
);
|
||
}
|
||
}
|
||
|
||
create() {
|
||
// Initialize localization
|
||
this.lang = new LocalizationManager(this.game);
|
||
this.lang.loadLanguage(savedLang);
|
||
|
||
// Use translations
|
||
const skipText = this.add.text(
|
||
width - 20, 20,
|
||
this.lang.getText('ui.skip'),
|
||
{ fontSize: '16px', color: '#888888' }
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎬 AUTOMATED GENERATION WORKFLOW
|
||
|
||
### **Master Script:**
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# generate_all_languages.sh
|
||
|
||
echo "🌍 Generating voiceovers for all 6 languages..."
|
||
|
||
# Slovenian (DONE)
|
||
echo "✅ Slovenian - already complete"
|
||
|
||
# English
|
||
./ai_voice_gen/generate_prologue_english.sh
|
||
|
||
# German
|
||
./ai_voice_gen/generate_prologue_german.sh
|
||
|
||
# Italian
|
||
./ai_voice_gen/generate_prologue_italian.sh
|
||
|
||
# Croatian
|
||
./ai_voice_gen/generate_prologue_croatian.sh
|
||
|
||
# Serbian
|
||
./ai_voice_gen/generate_prologue_serbian.sh
|
||
|
||
echo "🎉 All languages generated!"
|
||
echo "📊 Total files: 72 (12 per language × 6 languages)"
|
||
```
|
||
|
||
**Estimated Time:** ~20 minutes for all languages
|
||
|
||
---
|
||
|
||
## 📈 PRIORITY ORDER
|
||
|
||
### **Immediate (This Month):**
|
||
1. ✅ Slovenian (COMPLETE)
|
||
2. **English** (biggest market)
|
||
|
||
### **High Priority (Next Month):**
|
||
3. **German** (Steam top 3 market)
|
||
4. **Italian** (neighboring country, big gaming market)
|
||
|
||
### **Medium Priority (Q1 2026):**
|
||
5. **Croatian** (region similarity)
|
||
6. **Serbian** (region similarity)
|
||
|
||
---
|
||
|
||
## 🎯 NEXT STEPS
|
||
|
||
### **TODAY:**
|
||
1. Create `LocalizationManager.js`
|
||
2. Extract Slovenian text to `sl-SI.json`
|
||
3. Create `en-US.json` (English translation)
|
||
|
||
### **THIS WEEK:**
|
||
4. Generate English voiceovers (12 files)
|
||
5. Test language switching
|
||
6. Create language selector UI
|
||
|
||
### **NEXT WEEK:**
|
||
7. German + Italian translations
|
||
8. Generate voiceovers
|
||
9. Full integration test
|
||
|
||
---
|
||
|
||
## 📝 NOTES
|
||
|
||
**Why These 5 Languages?**
|
||
1. **English** - Global standard, Steam #1
|
||
2. **German** - Steam #2 market, high-quality gaming culture
|
||
3. **Italian** - Close to Slovenia, big indie game market
|
||
4. **Croatian** - Regional, similar culture, easy translation
|
||
5. **Serbian** - Regional, similar culture, Cyrillic option
|
||
|
||
**Alternative Languages to Consider:**
|
||
- **Russian** (huge market, but Cyrillic)
|
||
- **Spanish** (global, but less indie focus)
|
||
- **French** (big market, strict translation requirements)
|
||
- **Polish** (huge gaming market, Slavic language)
|
||
|
||
---
|
||
|
||
## ✅ SUCCESS CRITERIA
|
||
|
||
- [ ] All 6 languages fully translated
|
||
- [ ] 72 voiceover files generated (12 × 6)
|
||
- [ ] Language selector UI functional
|
||
- [ ] Runtime switching works seamlessly
|
||
- [ ] No performance impact
|
||
- [ ] Saved preferences persist
|
||
- [ ] All text uses localization system
|
||
|
||
**Target Launch:** All 6 languages available at **Early Access launch**
|
||
|
||
---
|
||
|
||
**Last Updated:** January 4, 2026
|
||
**Status:** Planning → Implementation Phase Starting
|