# 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 GetAvailableLanguages(); std::string GetCurrentLanguage(); bool IsTranslationLoaded(); private: std::string currentLanguage; std::map 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 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 |