¿Por qué no existía hasta ahora?
- La serie de aventuras point-and-click The Legend of Kyrandia, lanzada hace 35 años. De toda la serie, solo la segunda entrega, Hand of Fate, no había sido localizada al coreano.
- Entre los motores implementados en ScummVM, en casos como SCUMM de Lucas o SCI de Sierra sí existen bastantes traducciones fan al coreano, pero en el motor Kyra de Westwood casi no hay.
- Formato binario propio, renderizado de fuentes pensado solo para 1 byte, y además faltaban todas las fuentes necesarias.
- Para hacer la localización al coreano, no bastaba con extraer y traducir: también hubo que modificar el código de renderizado de texto del motor Kyra en ScummVM.
Traducción
- La traducción en sí no fue especialmente difícil; se tomó el script extraído y se pasó por un LLM para traducirlo.
- Solo se usó un prompt simple para mantener el tono del juego, y en general no parece haber problemas importantes.
- Eso sí, las partes más sutiles, como juegos de palabras o dobles sentidos, parece que no se traducen tan bien.
Ingeniería inversa
- Los formatos propios de Westwood: PAK (paquete), EMC (script de escena), DLG (diálogo), ENG (texto de UI).
- Se hizo ingeniería inversa de cada formato y se crearon herramientas en Python.
- EMC -> KMC, DLG -> DLK, ENG -> KOR; cada uno se generó con su traducción correspondiente y se guardó en
OTHER.PAK.
- Se modificó el código de ScummVM para que, en el caso de una traducción fan, cargue los archivos traducidos desde
OTHER.PAK.
- Sin dependencias externas, todo se compila con una sola línea:
$ python tools/build_korean.py; eso genera un archivo .zip, y basta con sobrescribir los archivos del juego original.
Fuentes
- Por defecto no había una fuente coreana, así que hubo que conseguir una.
- Existía una fuente coreana en el clásico distribuido oficialmente en Corea The Dig, y ya la tenía guardada.
- Como la estructura de la fuente era un poco distinta, se eliminó el encabezado.
- Se añadió a ScummVM un renderizador de fuentes coreanas.
- Por suerte, el sistema de fuentes para una traducción fan al chino ya incluía carga de mapas de bits, renderizado 1bpp, manejo de contornos e incluso combinación de 1 byte + 2 bytes (
MultiSubsetFont).
- Además, en Kyrandia 1 ya existía un sistema de fuente coreana de tipo combinatorio, así que también estaba la lógica para leer 2 bytes.
- Solo hubo que agregar la lógica que convierte pares de bytes de EUC-KR en índices de glifos.
- Había pensado hacer algo con la fuente japonesa de la versión FM-Towns, pero al final se resolvió fácilmente.
Guerra contra los bugs
- Bug de "gagagaga"
- La función
preprocessString() que ajusta diálogos largos al ancho de la pantalla estaba implementada tomando como base fuentes de 1 byte.
- Se insertaba un
\r en medio de un carácter de 2 bytes, el texto posterior se corrompía y terminaba mostrándose como "gagagaga".
- También hubo un error al cargar scripts de escena en la parte que referencia
_scriptLangExt, así que por accidente se cargaba japonés en su lugar.
- Como tampoco existía esa fuente correspondiente, volvía a mostrarse como "gagagaga".
- En ambos casos, la causa era que
getFontOffset devolvía 0 cuando no encontraba el carácter correspondiente; costó bastante arreglarlo para que funcionara bien.
- Game data not found
- A partir de la segunda ejecución, el programa se caía de forma extraña.
- En ScummVM, al salir del juego se guardaba el idioma como coreano, lo que hacía que la detección dejara de funcionar.
- Por ahora, la detección se hace como inglés, y si existe
KOREAN.FNT, eso se guarda en fanLang para procesarlo. Ese parece ser el enfoque correcto.
- Bug de Chunk overread
- Al parsear el script de escena localizado
KMC, el IFFParser de ScummVM arrojaba el error Chunk overread.
- Al empaquetar
KMC según el estándar IFF se guardó form_size = file_size - 8, pero resulta que solo Westwood guarda form_size = file_size.
- Como los offsets no coincidían, se producía el error.
Contribuir a ScummVM
- Las traducciones fan están soportadas oficialmente en ScummVM con el formato
FLAGS_FAN(KO_KOR, EN_ANY).
- La primera parte indica la traducción fan y la segunda el idioma original.
- Después de iniciar el motor, se hace el cambio en
kyra_hof.cpp, con lo cual se habilita el modo coreano real y se cargan los archivos traducidos.
- El sistema de extensiones de archivo cambia según el idioma; por ejemplo, para archivos DLG, en DOS el inglés usa DLE y el alemán usa DLG.
- Como el trabajo empezó con la versión de FM Towns y luego también se adaptó a DOS, de pronto empezó a aparecer alemán inesperadamente.
- Si no existe
KMC, se usa EMC, de modo que el juego puede funcionar incluso si la traducción no está completa.
- Ya se dejó un PR; no hubo tantas objeciones como se temía y al final solo hubo que ordenar los commits.
El potencial de la IA
- En la práctica, casi todo esto lo hicieron OpenCode y Opus / Sonnet.
- Lo que yo hice fue más parecido al rol de líder del proyecto: empujar, probar, depurar y animar al equipo (es decir, escribir prompts).
- Ya tenía reunidos todos los materiales, y probablemente podría haberlo hecho por mi cuenta, pero ni siquiera habría sabido por dónde empezar.
- Casi no escribí ni una sola línea de código en Python o C++, y terminé pensando que esto realmente se parece a hacer ingeniería junto con IA.
- Gracias a esto, creo que ahora tengo una visión más positiva sobre la programación con IA.
3 comentarios
Vaya, la pantalla del juego transmite totalmente esa nostalgia de otra época;;
Parece ser un juego como The Secret of Monkey Island. Se ve divertido.
Así es. Aunque sería exagerado llamarlo un rival, The Legend of Kyrandia también tuvo cierta popularidad gracias a su traducción al coreano. Jaja.