Files
Shiip-of-Hakinian-Espanol-A…/PLAN_TRADUCCION.md
2026-03-30 10:05:53 +00:00

259 lines
7.7 KiB
Markdown

# Plan de Implementación del Sistema de Traducción
## Objetivo
Crear un sistema de traducción dinámico que permita cargar idiomas desde archivos JSON externos **sin modificar los textos hardcodeados existentes**. Los textos en el código bleiben en inglés como fallback por defecto.
---
## 1. Funcionamiento Clave
### 1.1 Comportamiento
- **Sin carpeta de idiomas**: El juego funciona exactamente como ahora con los textos hardcodeados en inglés
- **Con carpeta de idiomas**: Cuando el usuario selecciona un idioma, se carga el JSON y se traducen los textos disponibles
- **Fallback**: Si una traducción no existe en el JSON, se usa el texto hardcodeado (inglés)
### 1.2 Carpeta de Idiomas (opcional)
```
/lenguajes/
├── Espanol.json
├── Portugues.json
└── (otros idiomas).json
```
**Nota**: No se requiere English.json porque el inglés ya está hardcodeado en el código.
---
## 2. Archivos a Crear
| Archivo | Descripción |
|---------|-------------|
| `soh/soh/SohGui/LanguageManager.h` | Header del manager de idiomas |
| `soh/soh/SohGui/LanguageManager.cpp` | Implementación del manager |
| `lenguajes/Espanol.json` | Traducción español (ejemplo) |
| `lenguajes/Portugues.json` | Traducción portugués (ejemplo) |
---
## 3. Archivos a Modificar
| Archivo | Cambios |
|---------|---------|
| `soh/soh/SohGui/SohMenuSettings.cpp` | Agregar selector de idioma dinámico en configuración |
**Nota**: Los demás archivos del menú NO necesitan modificación. La función de traducción se aplica automáticamente a todos los textos existentes.
---
## 4. Formato de Archivos JSON
### 4.1 Estructura del JSON
```json
{
"language": "Español",
"strings": {
"Settings": "Configuración",
"Enhancements": "Mejoras",
"Randomizer": "Randomizer",
"Network": "Red",
"Dev Tools": "Herramientas de Desarrollo",
"Enabled": "Activado",
"Disabled": "Desactivado",
"Apply": "Aplicar",
"Cancel": "Cancelar"
}
}
```
### 4.2 Espanol.json (Ejemplo)
```json
{
"language": "Español",
"strings": {
"Settings": "Configuración",
"Enhancements": "Mejoras",
"Randomizer": "Randomizer",
"Network": "Red",
"Dev Tools": "Herramientas de Desarrollo",
"General Settings": "Configuración General",
"Graphics": "Gráficos",
"Audio": "Audio",
"Controls": "Controles",
"Enabled": "Activado",
"Disabled": "Desactivado",
"On": "Activado",
"Off": "Desactivado",
"Yes": "Sí",
"No": "No",
"Apply": "Aplicar",
"Cancel": "Cancelar",
"Resolution": "Resolución",
"FPS Limit": "Límite de FPS",
"VSync": "Sincronización Vertical",
"Master Volume": "Volumen Principal",
"Music Volume": "Volumen de Música",
"SFX Volume": "Volumen de Efectos",
"Anti-aliasing (MSAA)": "Antialiasing (MSAA)"
}
}
```
---
## 5. Implementación del LanguageManager
### 5.1 LanguageManager.h
```cpp
class LanguageManager {
public:
static LanguageManager& Instance();
void Init();
void LoadLanguage(const std::string& languageName);
std::string GetString(const std::string& key);
std::vector<std::string> GetAvailableLanguages();
std::string GetCurrentLanguage();
bool IsTranslationLoaded();
private:
std::string currentLanguage;
std::map<std::string, std::string> translations;
bool translationLoaded;
void ScanLanguageFiles();
bool LoadJsonFile(const std::string& path);
};
```
### 5.2 Lógica de Funcionamiento
```cpp
std::string LanguageManager::GetString(const std::string& key) {
// Si no hay traducción cargada, retorna el texto hardcodeado (ingles)
if (!translationLoaded || translations.empty()) {
return key;
}
// Busca la traducción
auto it = translations.find(key);
if (it != translations.end()) {
return it->second;
}
// Si no encuentra la traducción, retorna el texto hardcodeado
return key;
}
```
### 5.3 Funcionalidades Principales
1. **Escaneo de idiomas**: Al iniciar, escanea la carpeta `/lenguajes/` y detecta archivos `.json`
2. **Carga bajo demanda**: Solo carga el JSON cuando el usuario selecciona un idioma
3. **Fallback seguro**: Si no existe la traducción, retorna el texto hardcodeado
4. **Selector dinámico**: Genera opciones basadas en archivos encontrados (sin hardcodear nombres)
---
## 6. Ejemplo de Uso en el Código
### 6.1 Sin cambios en el código existente
Los textos hardcodeados permanecen exactamente igual:
```cpp
// El código queda igual, NO se cambia a L("key")
AddWidget(path, "Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX);
AddWidget(path, "Enabled", WIDGET_CVAR_CHECKBOX);
```
### 6.2 La traducción se aplica automáticamente
La función `GetString()` intercepta los textos y los traduce:
```cpp
// Internamente en AddWidget o donde se muestra el texto:
std::string displayText = LanguageManager::Instance().GetString("Settings");
// Si hay español cargado, retorna "Configuración"
// Si no hay traducción, retorna "Settings" (el texto original)
```
### 6.3 Cómo funciona
- Los textos en el código bleiben en inglés
- La función `GetString()` se llama al momento de mostrar el texto
- Si hay una traducción cargada y existe la clave, retorna la traducción
- Si no hay traducción o no existe la clave, retorna el texto original (hardcodeado)
---
## 7. Selector de Idioma
### 7.1 Ubicación
En `SohMenuSettings.cpp` dentro del menú de configuración
### 7.2 Comportamiento
- Muestra todos los archivos `.json` encontrados en `/lenguajes/`
- El nombre del archivo (sin extensión) se muestra en el selector
- Al seleccionar un idioma, carga el archivo JSON correspondiente
- Por defecto (sin acción del usuario), funciona con textos hardcodeados
### 7.3 Ejemplo de implementación del selector
```cpp
// El selector se genera dinámicamente
std::vector<std::string> languages = LanguageManager::Instance().GetAvailableLanguages();
// languages = {"Espanol", "Portugues", ...} (nombres de archivos JSON)
// Mostrar en el menú
AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX)
.Options(languages);
```
---
## 8. Proceso de Implementación (Orden Sugerido)
### Fase 1: Fundamentos
1. Crear `LanguageManager.h/cpp`
2. Crear estructura de carpetas `/lenguajes/`
### Fase 2: Integración
3. Modificar `SohMenuSettings.cpp` para agregar selector de idioma dinámico
4. Conectar el selector con `LanguageManager`
### Fase 3: Pruebas
5. Crear `Espanol.json` de prueba
6. Probar cambio de idioma
---
## 9. Notas Importantes
-**Textos hardcodeados permanecen**: El código no se modifica, los textos en inglés quedan como están
-**Sin carpeta de idiomas funciona igual**: Si no existe la carpeta, el juego funciona exactamente como antes
-**Fallback automático**: Si falta una traducción, se muestra el texto original
-**Selector dinámico**: Los nombres de idiomas vienen de los archivos JSON, no están hardcodeados
-**Fácil agregar idiomas**: Solo hay que crear un nuevo archivo `.json` en la carpeta
---
## 10. Archivos de Referencia con Textos Hardcodeados
### SohGui (ya analizados)
- `SohMenu_hardcoded.txt`
- `SohMenuSettings_hardcoded.txt`
- `SohMenuEnhancements_hardcoded.txt`
- `SohMenuRandomizer_hardcoded.txt`
- `SohMenuNetwork_hardcoded.txt`
- `SohMenuDevTools_hardcoded.txt`
- `SohMenuBar_hardcoded.txt`
- `ResolutionEditor_hardcoded.txt`
---
## 11. Diferencias con el Plan Anterior
| Aspecto | Plan Anterior | Plan Actual |
|---------|---------------|--------------|
| English.json | Obligatorio | No necesario (hardcodeado es fallback) |
| Reemplazo de textos | Sí, en todos los archivos | No, solo agregar función GetString |
| Archivos a modificar | 8+ archivos | Solo 1 archivo (SohMenuSettings.cpp) |
| Funcionamiento sin carpeta | Requiere English.json | Funciona igual que antes |