20.04.2013

Localization

Die Umsetzung des Plots schreitet voran und die Engine beherrscht die nächste wichtige Stufe im Spiel: die Voraussetzungen für Übersetzungen sind geschaffen!

Ausgangslage

Im Spiel werden XML Dateien verwendet, um die Szenen sehr flexibel aufzubauen. Darin sind auch die gesprochenen Texte aller Figuren. Zur Zeit sind diese in deutsch geschrieben - es fiel mir leichter die Story in deutsch zu schreiben, als mir einen mit meinem Schulenglisch abzuwürgen. Da werden bei gegebener Zeit Profis übernehmen müssen…

Vorbereitungen

Um das Projekt auf die Internationalisierung (wird unter iOS als Localization bezeichnet) vorzubereiten, musste ich erst einmal mein Projekt auf den neusten Stand bringen. Unter den Projekt-Settings->Info->Localizations standen verschiedene, ungebrauchte oder falsche Localizations, etwa Japanisch oder zwei mal Englisch. Korrigieren ließ sich das nur, indem alle Einträge gelöscht wurden.

Finale Projekt Konfiguration

An dieser Stelle keimt aber ein Problem unter XCode 4.6. Der Klick auf das Plus für eine neue Sprache zeigt einen Wizard, bei dem man die grundlegende Sprachendatei auswählen muss, der aber leer ist… Oh man! Vermutlich ist das ein Verhalten, das sich ergibt, wenn man Projekte über XCode-Generationen hinweg mitschleppt…

Das Ganze lässt sich aber einfach lösen:

Zuerst wird die Datei “Localizable.strings” angelegt, indem man im Root des Projekts auf File->New->File… klickt. Im Wizard wählt man dann eine Vorlage vom Typ “iOS / Resource / String File” aus.

Es wird eine kurze Datei angelegt, die nun Key-Value Pairs aufnehmen kann. Sowohl die Keys als auch die Values werden mit doppelten Anführungsstrichen umklammert, denn die Keys sind die originalen deutschen Texte im Spiel.

"Das ist ein Teststring" = "Das ist ein Teststring";

Beendet wird jede Zeile mit einem Semikolon.

Diese Datei wird im Projekt-Root im Finder angelegt. Ich hatte zuerst mit dem Resourcen-Ordner experimentiert, aber das schien schlicht nicht zu funktionieren. Die aktuelle Position passt mir zwar nicht, aber ich lebe erst einmal damit.

Wird jetzt in den Projekt-Settings eine Sprache hinzugefügt, dann stellt XCode auch fest, dass es eine entsprechende Datei unter den Resourcen gibt und bietet diese an an den sprachenabhängigen Unterordner zu kopieren, z.B. de.lproj oder en.lproj.

Code

Nun muss der Code im Spiel einwenig umgeschrieben werden. zuerst wird die Klasse EventText zu EventLocaleText abgeleitet und im Resoure-Loader registriert. Hier wird eine Methode mit dem Namen getReadableText überschrieben. In diese wird folgender Snippet eingebettet:

return [[NSBundle mainBundle] localizedStringForKey:self.text 
			value:[NSString stringWithFormat:@"*i18n: %@*", self.text] 
			table:nil];

Da ich nicht möchte, dass fehlerhafte, unübersetzte Texte nicht spurlos am Tester vorbeigehen, wird hier im Fehlerfall “*i18n: unübersetzter Text*” ausgegeben. Das ist auffällig genug, um Fehler bei der Übersetzung schnell finden zu können.

Vor allem, im späteren Verlauf der Spielentwicklung erhoffe ich mir hier einwenig mehr Sicherheit. Im besten Fall sieht der Tester bzw. final der Spieler keine dieser Meldungen.

Test

Der erste Test verlief nicht vielversprechend. Die Daten wurden nicht wie erwartet im Spiel verwertet. Letztendlich haben diese Schritte die Resourcen aktiviert:

Jetzt waren die Änderungen nach dem Sprachenwechsel sichtbar… wunderbar…

Build

In dem jeweiligen Ordner liegen nun die Localizable.strings. Üblicherweise werden die Projektdateien mittels des Programms “genstrings” durchsucht und die primäre Datei gefüllt. Das trifft in Argh! Earthlings! nicht zu, denn im Code wird man keine sinnvoll übersetzbare Textstelle finden. Alle darzustellenden Texte werden aus den Spiel-Definitionen (xml) geladen.

Um mir die Arbeit zu erleichtern habe ich mir ein Script geschrieben, das mir die xml-Dateien scannt, die Passagen mit den Texten extrahiert, säubert (escape) und in eine neue Localizable.strings-Datei unter de-autogen.lproj speichert.

Diese Localizable.strings beinhaltet nun alle Key-Values Pairs, auch die, die doppelt verwendet wurden.

Also muss ein weiteres Vorgehen her, das die Datei nun auf die einzigartigen Zeilen reduziert. Da Ganze ist unter bash sehr entgegenkommend:

cat $INPUT | grep -v "//" | sort -u >> $OUTPUT

Voilà! Die Texte werden sauber alphabetisch sortiert, ohne Redundanzen in eine weitere Datei geschrieben. Diese neue Datei erhält nun einige Extradaten in den Dateinamen eingearbeitet:

Später erhält diese Datei, passend zu den vorhandenen Locales, noch einen ISO-639 Suffix, wie en, fr oder es, damit man die Sprache schon von außen erkennen kann. Damit wären die Dateien für zukünftige Übersetzungs-Arbeiten einsatzbereit.

Stand der Dinge

Allerdings ist es noch ein weiter Weg, bis sich das Konzept bewahrheitet.

Der erste Test spuckte bereits über 1000 Zeilen aus, die übersetzt werden wollen. Der Plot ist zu ungefähr 50% fertiggestellt. Ich bin mal gespannt, wie viel Text am Ende zusammenkommen wird…


20.04.2013