11 puntos por colus001 2026-03-26 | 3 comentarios | Compartir por WhatsApp

¿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

 
roxie 29 일 전

Vaya, la pantalla del juego transmite totalmente esa nostalgia de otra época;;

 
computerphilosopher 2026-03-26

Parece ser un juego como The Secret of Monkey Island. Se ve divertido.

 
colus001 2026-03-26

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.