How to translate a game’s .po and .mo files (gettext)
The .po is the editable source; the .mo is the compiled catalog the game actually loads — which is why editing the .po alone changes nothing. RuneTranslate reads both, protects %s and {count} placeholders, refits plural forms to your language, and writes a working .mo back.
Si has abierto la carpeta de un juego y has encontrado un directorio locale lleno de archivos .po y .mo, ese juego está localizado con gettext — y RuneTranslate ya puede traducirlo de principio a fin, desde la creación del proyecto hasta exportar una compilación jugable.
Esta guía explica qué son realmente esos dos tipos de archivo, por qué editar el que puedes leer normalmente no cambia nada en el juego, y cómo traducirlos correctamente.
.po frente a .mo — la distinción con la que todo el mundo tropieza
Son dos formas del mismo catálogo:
- `.po` — Portable Object. Un archivo de texto plano que puedes abrir en cualquier editor. Cada entrada tiene un
msgid(la cadena original) y unmsgstr(su traducción). Es el archivo en el que trabajan los traductores. - `.mo` — Machine Object. Una versión binaria compilada de los mismos datos, dispuesta para que el juego localice una cadena al instante. Este es el archivo que lee el juego en ejecución.
Ese último punto es el que le cuesta una tarde a mucha gente. Puedes traducir cada línea de un .po, guardarlo, lanzar el juego — y no ver ningún cambio, porque el juego nunca abre el .po. Carga el .mo que está a su lado, que sigue conteniendo el texto antiguo. Normalmente compilarías uno en otro con msgfmt, de las herramientas GNU gettext. RuneTranslate escribe ambos, así que no hay un paso de compilación aparte.
Cómo es la carpeta de un juego con gettext
La estructura canónica es un directorio locale indexado por código de idioma:
MyGame/game.exeMyGame/locale/en/LC_MESSAGES/mygame.moMyGame/locale/fr/LC_MESSAGES/mygame.moMyGame/locale/de/LC_MESSAGES/mygame.mo
La carpeta LC_MESSAGES forma parte de la convención, no es un error, y mygame es el dominio de texto: el nombre que el juego pide al cargar sus cadenas. Muchos juegos usan en su lugar una forma más plana, como lang/fr.po, y también funciona.
¿Qué juegos usan gettext?
Gettext nació en el mundo Unix y se convirtió en la forma habitual de localizar software escrito en C, Python y todo lo basado en GTK. En juegos eso significa:
- Juegos en Python y pygame
- Solarus, SDL y otros motores en C/C++
- Juegos localizados con Poedit, Weblate o Crowdin, que hablan PO de forma nativa
- Algunos proyectos de Godot, que admiten PO como fuente de traducción
Es mucho más común en juegos indie occidentales que en los japoneses: motores japoneses como Kirikiri y RPG Maker guardan su texto en sus propios formatos.
Traducir un juego con gettext usando RuneTranslate
- Apunta RuneTranslate a la carpeta del juego. La que contiene
locale/,lang/oi18n/. La detección lee los bytes reales en lugar de fiarse de la extensión, así que un.moque en realidad es una escena 3D se ignora en vez de generar un proyecto roto. - Revisa el resumen. Antes de crear el proyecto verás el número de catálogos, el reparto entre
.mocompilados y.pofuente, los idiomas que el juego ya incluye y el total de cadenas. - Elige un idioma y un proveedor. Google o DeepL gratis, o tu propia clave de DeepL, OpenAI, Claude o DeepSeek — consulta la comparativa de proveedores.
- Revisa y exporta. Obtendrás una copia completa del juego con la traducción ya aplicada.
Las dos cosas que rompen en silencio una traducción gettext
Los marcadores. Un msgid es una cadena de formato, no prosa terminada. En Hello, %s! el nombre del jugador se sustituye en tiempo de ejecución. Los traductores automáticos tienden a eliminar %s, a separarlo con espacios o —con la forma con nombre de Python, %(player)s— a traducir la palabra de dentro. Las consecuencias no son estéticas: un %s perdido desplaza todos los argumentos posteriores y la mayoría de los motores se cierran. RuneTranslate enmascara cada marcador que encuentra (%s, %d, %(player)s, {count}, {0}) antes de enviar el texto al proveedor, y lo restaura después.
Las formas plurales. El inglés tiene dos («1 coin» / «5 coins»). El japonés y el turco, una. El ruso y el polaco, tres. Un catálogo declara en su cabecera cuántas usa, y si ese número no coincide con el idioma, gettext indexa más allá del final de la lista y recurre en silencio al original sin traducir. RuneTranslate ajusta las formas a tu idioma de destino y reescribe la cabecera en consecuencia.
Por qué la exportación escribe el catálogo dos veces
La exportación produce tanto un idioma nuevo correcto —locale/<tu idioma>/LC_MESSAGES/— como una copia actualizada del catálogo que el juego ya estaba cargando.
Lo segundo es lo que hace que la traducción aparezca de verdad. Un juego decide qué idioma cargar por vías que la carpeta no revela: puede leer el idioma del sistema, un archivo de configuración, un parámetro del lanzador, o tenerlo fijado en el código. Añadir un catálogo en español a un juego que solo pide inglés te dejaría mirando una compilación aparentemente idéntica. Sobrescribir el catálogo que sí carga elimina las conjeturas. Ambas cosas ocurren únicamente en la copia exportada: tu carpeta original no se modifica.
Las cadenas que no hayas traducido conservan la traducción que el juego ya traía, de modo que un proyecto a medias nunca vacía la localización del propio desarrollador.
Lo que esto no puede hacer
Solo se puede traducir el texto que ya está en un catálogo. Si un desarrollador escribió una cadena directamente en el código en lugar de pasarla por gettext, no está en el .po ni en el .mo, y ninguna herramienta PO puede encontrarla ahí. Es un límite del formato, no de la herramienta.
RuneTranslate también trata el msgid como texto de origen, que es lo que especifica el propio gettext. Algunos proyectos ponen msgids en inglés mientras el idioma original real está en msgstr; esos se traducirán desde el inglés.
Por último, si el juego funciona sobre un motor compatible directamente —Godot, Unity, Ren’Py— lo gestiona ese motor, de forma que también sea accesible el resto del texto del juego y no solo sus catálogos.
Antes de compartirlo
Lanza la compilación exportada y lee unas cuantas pantallas. Los menús y los botones son la comprobación más rápida, porque ahí es donde vive la mayor parte del texto del catálogo. Si algo falla —el juego no se detecta, lo exportado no arranca o el texto sigue en el idioma original— repórtalo desde el menú de Ayuda de la aplicación o en Discord. Descarga RuneTranslate y abre tu primer catálogo.
¿Listo para probar RuneTranslate?
El plan gratuito desbloquea todos los motores y todos los proveedores de traducción. Supporter ($3/mo) desbloquea la velocidad completa.
Descargar para Windows