Una traducción aficionada de cuentos visuales, en comparación con las traducciones de otros juegos, tiene varias características e implica trabajar con mucho texto. Quizás la gran mayoría de todas las novelas visuales fueron lanzadas en japonés, solo unas pocas fueron traducidas al inglés (oficialmente o por aficionados), y aún menos fueron traducidas a otros idiomas.
Por lo tanto, al trabajar con la traducción, debe tratar con motores japoneses, muchos de los cuales no son muy amigables con los localizadores. Debido a esto, rápidamente nos damos cuenta de que la presencia de habilidades de traducción, conocimiento del idioma, mucho entusiasmo y tiempo libre no significa en absoluto que la versión traducida del juego pronto verá la luz del día.
En términos generales, el proceso de traducir cualquier juego (no solo historias cortas visuales) implica:
- Desempaquetar recursos del juego (si no están en el dominio público)
- Traducción de partes necesarias
- Transferencia de embalaje inverso
Sin embargo, en el caso de las historias cortas visuales japonesas, esto generalmente se ve así:
- Desempaquetar recursos del juego
- Traducción de la parte de texto del juego (guión del juego)
- Traducción de la parte gráfica del juego.
- Transferencia de embalaje inverso
- Alteración del motor para que funcione con contenido traducido
Espero que nuestra experiencia sea útil para alguien.
En 2013 (y posiblemente antes) decidí traducir del japonés la novela visual Bishoujo Mangekyou-Norowareshi Densetsu no Shoujo- (美 少女 万 華 鏡 - 呪 わ れ し 伝 説 の 少女 -). Ya tenía experiencia en la traducción de juegos, pero antes tenía que traducir solo historias cortas en motores relativamente simples y conocidos como
Kirikiri .
Aquí, nuestro equipo de traductores tuvo que abrir el motor de esta historia corta, incluso antes de llegar al texto en sí.
Comencemos con una descripción del archivo .exe, donde se mencionan las palabras QLIE e IMOSURUME. El archivo en sí contiene la línea FastMM Borland Edition 2004, 2005 Pierre le Riche, lo que significa que el motor probablemente esté escrito en Delphi.
Una búsqueda rápida en Google revela que Qlie es el nombre del motor de novela visual lanzado por Warmth Entertainment. Aparentemente, IMOSURUME es el nombre interno del motor de script, y Qlie es el nombre comercial. Hay un sitio
qlie.net , que enumera los juegos lanzados en este motor y el sitio web oficial de Warmth Entertainment.
Pero en ninguna parte del dominio público no hay herramientas oficiales para trabajar con el motor, ni documentación para ello, lo que se espera.
Por lo tanto, debes lidiar con el juego tú mismo, confiando en utilidades no oficiales. Para empezar, debes encontrar todas las partes del juego que necesitan ser traducidas.
Los archivos del juego se encuentran en los archivos data0.pack, data1.pack y data7.pack en la subcarpeta \ GameData. Los protectores de pantalla están en la carpeta \ GameData \ Movie, pero aún puede dejarlos solos.
El editor hexadecimal muestra que no hay encabezados reconocibles para los archivos .pack del juego, pero al final del archivo hay una pieza similar a la tabla de contenido y la etiqueta FilePackVer3.0
Afortunadamente, para este formato, ya hay un desempacador y ni siquiera uno. Utilizamos la consola exfp3_v3 de asmodean.
Desempacar no es tan fácil como parece. Dado que el motor admite varios formatos de archivo (FilePackVer1.0, FilePackVer1.0, FilePackVer3.0), y en este caso se utiliza FilePackVer3.0, para el desempaquetado correcto también necesitará un archivo de clave especial key.fkey, que cifró el archivo. Se encuentra en la subcarpeta \ Dll
Además, exfp3_v3 debería aclarar el archivo desde el que se está descomprimiendo el juego.
Por lo tanto, también debe especificar el número de juego de la lista propuesta por el desempacador (los juegos de la serie Bishoujo Mangekyou están bajo el número 15), o especificar el archivo ejecutable del juego como el tercer parámetro para el desempacador.
Ya después de desempaquetar los archivos del juego, surgió un pensamiento lógico: ¿cómo en el futuro cómo empacar el juego con una traducción lista? Después de todo, el desempacador no admite la operación inversa.
A petición nuestra, w8m (muchas gracias por eso) agregó la capacidad de empaquetar archivos del juego en su programa arc_conv.exe. Es suficiente empacar todos los archivos modificados en un nuevo archivo (por ejemplo, data8.pack), colocarlo en la carpeta GameData y se incorporarán automáticamente al juego.
Volver a los recursos desempaquetados. Los archivos de script del juego del archivo data0.pack se pueden encontrar en la subcarpeta \ escenario \ ks_01 \
Todos los archivos de script con la extensión .s están codificados lejos de la codificación Shift Jis más conveniente, y el motor no admite codificaciones Unicode. Las líneas para la traducción se parecen aproximadamente a estas:
【キリエ】 %1_kiri1478% 「へえ……分かっているじゃない」 私が献上したロシアンティーを見て、キリエは嬉しそうに目を細める。 ^cface,,赤目微笑01 【キリエ】 %1_kiri1479% 「日本人は、ジャムを紅茶に入れて飲むのが、ロシアンティーだと勘違いしている人が多いのだけれど……」
Puede notar que cada frase en japonés está precedida por el nombre del héroe entre paréntesis japoneses. (【】), Que pronuncia esta frase (en el juego se muestra en la parte superior de la ventana con texto). O, si estas son las palabras del autor, entonces el nombre no se agrega.
Pero todavía hay equipos de servicio.
Los comandos del motor en el script recuerdan un poco el lenguaje de marcado TeX, pero son mucho más intuitivos e inconvenientes en comparación con los
comandos Kirikiri o
RenPy .
Aquí hay algunos de ellos:
@@@
es un perro triple. A menudo, los archivos de comandos comienzan con este comando. Aparentemente cargando definiciones de archivos de terceros.
Por ejemplo:
@@@Library\Avg\header.s
@@
es un perro doble. La etiqueta en el archivo de script. Puedes cambiarlo más tarde.
%1_kiri1478%
: reproduce el archivo de voz. Estos comandos se insertan entre el nombre del héroe y el texto que se muestra en la pantalla. “1_kiri1478”: en este caso, el nombre del archivo de la carpeta \ voice \ del archivo data1.pack Es interesante que el equipo use el porcentaje japonés (%), en lugar del habitual.
^savedate, ^saveroute, ^savescene,
- tres equipos que probablemente se usan en el sistema de guardado del juego y deben ingresar información sobre el lugar y la hora en que el jugador se guardó en el juego guardado.
Por ejemplo:
^savedate,"現在" ^saveroute,"美少女万華鏡-1-" ^savescene,"呪われし伝説の少女 オープニング"
Es decir, fecha: presente, rama: Bishoujo Mangekyou -1-, escena: Norowareshi Densetsu no Shoujo Opening. Estos datos deberían haberse mostrado en la ranura de guardado, pero aparentemente los desarrolladores decidieron abandonarlos. Como resultado,
^saveroute
en todas las partes del guión,
^savedate
cambia de "el momento presente" a "sueños", y en
^savescene
días (o más bien las noches) en el juego.
^facewindow,
- estado del cuadro de texto con el texto que se muestra en la pantalla. (Se muestra - 1 o no - 0)
^sload,
- reproduce sonidos en el juego desde la carpeta \ sound \ en el canal correspondiente.
sload,Env1,◆セミ01アブラゼミ
Tocando cigarras en Env1
El equipo tiene dos parámetros opcionales, el primero es responsable de reproducir el sonido y el segundo sigue siendo un misterio, pero rara vez se usa en el juego.
^sload,SE1,■クチュ音01,1
Reproducción de sonido loopback en el canal SE1.
^eeffect
: muestra un efecto especial en la pantalla durante un cierto número de segundos. Aparentemente, admite salida secuencial de varios efectos.
^eeffect,WhiteFlash
El efecto de un destello blanco.
^ffade
- efecto de transición al cambiar la pantalla.
Tiene un montón de parámetros adicionales, pero solo unos pocos son realmente útiles: el nombre del efecto de transición, una imagen adicional, si es necesario, y el tiempo de finalización de la transición.
^ffade,Overlap,,1000
Disolviendo una imagen en otra, en 1 segundo.
^iload
: carga la imagen de fondo en la pantalla. A la imagen se le puede asignar una identificación para hacer referencia en el futuro.
^iload,BG1,0_black.png
Archivo de salida 0_black.png como fondo con id BG1
^we
and
^wd
:
^wd
y desactiva la imagen en la ventana.
^facewindow,1
y
^facewindow,0
Activa y desactiva la imagen del héroe en el cuadro de diálogo.
^mload
: reproduce música en un canal específico.
^mload,BGM1,nbgm13
Reproduciendo la pista nbgm13 en el canal BGM1
Algunos de los equipos más importantes:
\jmp
: salta a la etiqueta con el nombre especificado.
^select
: muestra la ventana de selección en la pantalla, donde el jugador debe elegir una de las opciones.
Por ejemplo:
^select, , \jmp,"@@route01a"+ResultBtnInt[0] @@route01a0
Aquí la transición se realizará después de la respuesta a la pregunta, y el número de respuesta (0 o 1) se devuelve desde ResultBtnInt [0]. Como resultado,
\jmp
moverá la historia a la etiqueta @@ route01a + número de respuesta. Es decir, @@ route01a0 o @@ route01a1
Una característica desagradable es que la coma habitual en estos comandos sirve como separador y no se puede usar en las opciones de respuesta. Los japoneses no tienen ese problema, usan la coma japonesa (、). En este caso, podemos reemplazar la coma con ‚(U + 201A SINGLE LOW-9 COOT MARK).
Por ejemplo:
^select, ‚ , ‚
Los equipos restantes no son tan importantes en la primera aproximación.
Por supuesto, antes de traducir el script, debe transcodificarlo en algo más conveniente, por ejemplo, en UTF-8, para combinar caracteres cirílicos y japoneses.
Después de cambiar el motor (sobre la siguiente parte), el juego percibe tanto el texto ruso como el japonés. Pero por ahora, por compatibilidad, debe codificar los caracteres japoneses en Shift Jis y los caracteres cirílicos en la codificación cp1251.
Esbozamos rápidamente un programa en Python para transcodificar teniendo en cuenta el alfabeto cirílico:
Sin embargo, hubo algunos problemas. El programa, al intentar recodificar el símbolo de "tilde" U (U + FF5E FULLWIDTH TILDE), generó un error "UnicodeEncodeError: el códec 'Shift Jis' no puede codificar el carácter '\ uff5e' en la posición 0: secuencia multibyte ilegal"
Al principio, pequé en Python, pero al final descubrí un matiz bastante inusual. Existe una incertidumbre entre los métodos de correlación de codificaciones japonesas Unicode y no Unicode dependiendo de la implementación específica.
Como resultado, Windows asocia el carácter Shift Jis con el código 0x8160 con el unicode ~ (U + FF5E FULLWIDTH TILDE) y otros transcodificadores (por ejemplo, la utilidad iconv) correlacionan el mismo carácter con 〜 (U + 301C WAVE DASH), de acuerdo con la tabla oficial de relaciones Unicode -
ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFT JIS.TXTPara determinar la correspondencia entre los personajes, Microsoft aparentemente decidió usar los esquemas de su codificación cp932, que es una versión extendida de Shift Jis.
La misma situación ocurre con el código de carácter 0x817C, que se transcodifica a UTF8 como - (U + FF0D FULLWIDTH HYPHEN-MINUS) en Windows, o como - (U + 2212 SIGNO MENOS) en iconv.
Dado que todos los archivos de script se convirtieron por primera vez de Shift Jis a UTF8 usando Notepad ++ (y usa la tabla de correspondencia adoptada en Windows), al volver a convertir de UTF8 a Shift Jis a través de nuestro programa Python, apareció el notorio error de conversión.
Por lo tanto, era necesario tener en cuenta la aparición de ~ y - condiciones separadas.
Hubo otros defectos menores, por ejemplo, la elipsis ... (U + 2026 ELIPSIS HORIZONTAL) fue reemplazada por la elipsis cirílica de cp1251, y no los japoneses de Shift Jis.
Después de traducir el texto, puede continuar trabajando con los gráficos del juego.
Los archivos gráficos del juego se encuentran en los mismos archivos del paquete, pero después de desempaquetar, todavía tienen que trabajar duro. Por ejemplo, casi todas las imágenes png se descomprimen en forma de archivos del tipo de muestra + DPNG000 + x32y0.png En otras palabras, las imágenes png se cortan en tiras horizontales con un grosor de 88 píxeles y cada tira se graba en un archivo separado. El nombre del archivo muestra el número de serie de la tira (DPNG000 ... 009) y las coordenadas x, y.
Todavía me pregunto por qué esto era necesario. Si por la dificultad de extraer recursos del juego, claramente este no es el mejor método.
Para pegar los archivos png cortados, se creó un pequeño script merge_dpng en Pearl desde asmodeus, que usa ImageMagick, al mismo tiempo. Desafortunadamente, hubo problemas con él. En primer lugar, necesitaba Pearl, que no usé, e incluso después de instalarlo, resultó que el script no funcionaba correctamente.
Por esta razón, escribimos un programa similar en python:
Qlie motor dpng fusión de archivos ¿Parece que ahora tenemos todo el conjunto de imágenes que aparecen en el juego? Para nada: si mira todas las imágenes conectadas de todos los archivos, todavía encontrará que faltan algunas, aunque están en el juego. El hecho es que hay otro tipo de archivo en el motor, con la extensión .b. Es una especie de animación con imágenes y sonidos grabados en su interior.
Es bastante fácil obtener los recursos almacenados en su interior, pero, desafortunadamente, ninguno de los desempacadores de archivos .b ya funcionaba en nuestro caso como debería. O algunos archivos permanecieron sin empaquetar, o hubo errores debido a nombres japoneses, y no quería arrancar desde la configuración regional japonesa.
Aquí uno más nuestro script fue útil. Desde entonces no estábamos familiarizados con algo como
Kaitai Struct , tuvimos que actuar casi desde cero.
El formato de los archivos .b resultó ser simple y, además, nuestro descomprimidor debía poder descomprimir recursos solo de este juego. En otros juegos en el motor Qlie, aparecieron tipos adicionales de recursos dentro de los archivos .b, pero no nos detendremos en ellos en detalle.
Entonces, abra cualquier archivo .b en un editor hexadecimal y mire hacia el principio. Antes de evaluar, tenga en cuenta que el orden de bytes de todos los valores numéricos será Little-endian.
- Encabezado de archivo abmp12
- Diez bytes 0x00
- El título de la primera sección abdata12 con información general.
- Ocho bytes 0x00
- Tamaño de sección abdata12, entero de cuatro bytes. Puedes saltartelo con seguridad.
- Encabezado de sección Abimage10
- Siete bytes 0x00
- Número de archivos en una sección, entero de un solo byte. En este caso, hay un archivo en la sección.
- Encabezado de sección abgimgdat13
- Seis bytes 0x00
- La longitud del nombre del archivo dentro de la sección, un entero de dos bytes. En este caso, la longitud es de 4 bytes.
- Shift Jis nombre de archivo codificado
- Longitud de registro de suma de comprobación de archivo, entero de doble byte.
- La suma de comprobación del archivo en sí.
- El byte desconocido parece ser siempre 0x03 o 0x02
- Doce bytes desconocidos, posiblemente relacionados con la animación.
- El tamaño del archivo png dentro de la sección es un entero de cuatro bytes.
Y finalmente, el archivo png en sí.
La sección de absound es similar en estructura a abimage.
El script debe descomprimir automáticamente los archivos png, jpg, bmp, ogg y wav encontrados. Pero además de esto, también se encuentran archivos imoavi desconocidos en su interior.
La conclusión es que en el juego todas las animaciones se realizan como un video completo en formato ogv, o como imágenes animadas del motor que se graban en archivos .b, o como secuencias animadas de archivos jpg en formato imoavi.
En este caso, también estábamos interesados en las imágenes jpg, por lo que también tuvimos que lidiar con ellas.
Hay dos secciones en imoavi: SOUND y MOVIE. En la sección MOVIE, 47 bytes después del encabezado, hay cuatro bytes del tamaño del archivo jpg. Los archivos se escriben uno tras otro en su forma original, separados por una secuencia de 19 bytes, donde se registra el tamaño del siguiente archivo.
El imoavi sonoro en el juego no apareció, por lo que la sección de SONIDO siempre está vacía.
Bueno, desde que comenzamos a extraer todos los recursos del juego, al mismo tiempo se escribió un pequeño guión para extraer jpg de imoavi.
Después de desempaquetar, puede asegurarse de que la animación de la pantalla de bienvenida en el menú esté almacenada solo en el archivo 1_ タ イ ト ル 画面 ム ー ビ ー .b en el formato imoavi.Eso es todo con los recursos del juego.Desafortunadamente, el proceso de traducción reveló varios matices más desagradables que no se pudieron superar. El juego, como ya escribí, no admite codificaciones Unicode. Por lo tanto, todo el texto traducido se muestra con el espacio entre letras incorrecto. Hubo algunos problemas más con el empaquetado de archivos y el inicio del juego sin cambiar la codificación del sistema a japonés.En algún momento, nosotros (o mejor dicho, el responsable de la parte técnica de la traducción en nuestro equipo) pensamos: ¿tal vez no deberíamos quedarnos con el viejo motor, sino portar la novela al motor Renpy, al mismo tiempo obtener multiplataforma?Quizás teníamos prisa, pero en algún momento, fue una pena dejar lo que empezamos y no quedaba nada más que terminar la traducción.¿Qué encontramos durante la portabilidad?Sobre esto en la segunda parte.Enlaces:Nuestros scripts de bitbucketAcerca de latabla de codificación Shift Jis del motor Qlie japonésLea más sobre el problema de la transcodificación de Shift Jis a la utilidad exfp3_v3 asmodean UTF-8