frd's blog

Localización - Devlog #01

Hai uns anos tiven unha época onde vía moitos vídeos de devlogs en YouTube, xente en espazos indie comentando como pouco a pouco ían creando os seus videoxogos e falando de que aspectos foran os máis complicados de abordar. E unha das poucas leccións que me quedou gravada desa época é que, se queres localizar un xogo, tes que empezar dende o minuto 1 con iso en mente, porque se non despois é un absoluto coñazo e toca perder moito tempo. Así que decidín facer iso mesmo: implementei os aspectos máis básicos do xogo (os naipes e unha baralla con cartas en orde aleatoria que podes roubar) e agora toca a parte divertida, o marabilloso mundo da localización de videoxogos, e as decenas de solucións que existen.

Parte 1: por onde empezar?

Como dicía "el Chocu": JAJA SI. E como dicía o xkcd 927:

xkcd standards

A maioría de motores grandes teñen xa os seus propios plug-ins de localización, coa súa GUI ben bonita e a súa implementación xa ben feitiña. Non é o caso con raylib. Tes que buscar ti que solución utilizar.

Podes usar CSVs. Pero queres usar CSVs? Ou podes usar JSONs. Pero queres lidiar con ese formato tan feo? Ou tamén podes usar unha ferramenta de GNU que parece complicada de carallo de utilizar, pero que ten xa a súa libraría de C coas súas funcións. Pero queres aprender a utilizala? Ou tamén podes utilizar calquera outra cousa, que hai moitísimas máis e seguro que hai algunha mellor que se me pasou por alto.

Eu escollín ó final utilizar a movida de GNU, gettext. Traballa con ficheiros .po, que parece que son "o estándar" e teñen varias ferramentas construídas ó seu redor, así que ben por esa banda. Ademais, ten un comando (xgettext) que escanea polas cadeas que sexan necesarias reemplazar os ficheiros orixe que ti lle pases, cousa que está moi chula. Canta máis automatización mellor. Vai tocar mirar como funciona.

Parte 2: odio gettext

Menudo coñazo de ferramenta. Menudo asco. Cousa máis abxecta. A documentación de GNU ben podería non existir. Odio que hoxe en día a metade das páxinas web que explican o uso de comandos de Linux non sexan máis que muros de texto regurxitado pola IA xerativa de turno. Odio a miña vida. Odio este proxecto.

Parte 3: hai ben no mundo

Por unha banda, atopei este blog de aquí, que di unha cousa moi útil que vou ter en conta durante o resto do desenvolvemento deste videoxogo:

[...] I’d recommend a hierarchical structure (like nested classes or tables) that you collapse into a long name (INTRO.HARASSMENT.001_GARY_SHOUTING_HI) [...]

Isto é útil por dous motivos. O primeiro é que axuda a contextualizar de forma sinxela a localización e uso das diferentes cadeas de texto. Eu sei que o meu "button.quit" vai referirse sempre ó botón para saír do xogo e a ningunha cousa máis. O segundo é que axuda a visualizar as cadeas que aínda non están traducidas. Se gettext non atopa tradución ó idioma seleccionado, vai devolver a cadea orixinal. Moi bo para saber cando fallan as cousas.

Por outra banda, atopei estoutro blog. Non sei quen es, erri120, pero espero que nunca teñas unha noite de mal sono na túa vida. Salvoume completamente. Moi ben explicado o uso dos diferentes comandos de gettext, que vai onde e que facer cando. Tamén ten unha plantilla para integrar todo gettext en CMake que pensei en seguir pero, sinceramente, se hai algo que me guste menos que o fascismo é CMake. Así que creei 3 scripts pequerrechos, un para crear o template, outro para crear o ficheiro para unha linguaxe específica (ou facer merge se é que xa existe) e un último para compilar os .po en .mo, porque si, resulta que hai que compilalos, se non gettext non os le. Este último script si que o executo dende CMake, por comodidade máis que outra cousa, pero os outros dous pareceume estúpido metelos tamén, non é necesario telos aí.

Parte 4: desesperación e luz ó final do túnel

Bueno, fagamos comprobación da checklist:

Jaja. Que ben.

Por algún motivo, o programa estaba a cargar a tradución ó inglés sen problema, pero se dentro do xogo intentaba cambiar ó castelán, non sucedía nada. Intentei cambiar a parte na inicialización de gettext para que me cargase o castelán por defecto, pero isto foi peor, agora aparecianme as cadeas directamente sen traducir.

A orixe deste erro? gettext só cambia de idioma se tes o locale dese idioma instalado no sistema. Eu tiña só instalados galego e inglés. Entón non estaba atopando o castelán (aínda que tiña o ficheiro de tradución ben indicado na inicialización do servizo). A solución? Facerlle crer á ferramenta que o locale si está instalando chamando xusto antes do cambio de idioma a unha función para cambiar a variable de entorno LANGUAGE ó código do novo idioma. Dalgún xeito isto funciona. Non me vou queixar. O problema é que creo que esta solución non é portable a Windows. Problema para o eu do futuro.

Aínda así, aquí non acabou esta odisea, aínda quedaba un último rescollo antes de chegar a Ítaca. Empecei a tradución ó galego, e claro, button.quit ten que ser SAÍR. Aí descubrín que tódolos meus ficheiros de tradución estaban sendo lidos como ASCII, porque a miña plantilla estaba en ASCII. A solución? No script que teño para xerar a plantilla, engadir unha chamada a sed para remplazar ASCII por UTF-8, porque parece ser que xgettext non ten esa opción por defecto (ou non que eu atopase).

Ás veces odio programar. Terían que pagarme moito para deixar de facelo.

Parte 5: seguintes pasos

Agora tocará facer outras cousas do videoxogo, supoño. Máis interesantes e espero que máis sinxelas. Creo que o primeiro que vou facer vai ser mirar como escalar os obxectos dentro da ventá, xa que agora mesmo manteñen o tamaño en píxeles, independentemente do tamaño da ventá. Cando fixen o visualizador de nubes de puntos, descubrín que se pode definir un viewport, que escala os obxectos contidos dentro automaticamente. Vou mirar a ver se podo tirar por aí. Máis adiante xa me centrarei en facer o videoxogo en si.

← Devlog #00 (máis tarde) Devlog #02 →

#devlog #escoba #videoxogos