Unreal-Engine-Spiele übersetzen
Unreal-Spiele liefern ihren Text in kompilierten .locres-Tabellen in .pak- oder IoStore-Containern aus. So liest du sie — und warum die Ausgabe ein winziges Override-Pak ist statt eines neu gebauten Spiels.
Ein Unreal-Engine-Spiel sieht aus wie das Schwerste auf deiner Festplatte zum Übersetzen. Es gibt keinen data-Ordner, keine Skriptdateien, keine .json, die du öffnen kannst — nur eine ausführbare Datei, ein Content/Paks-Verzeichnis mit einer oder zwei riesigen .pak-Dateien und vielleicht ein Paar .utoc/.ucas-Container. Die gute Nachricht ist, dass der Text, den du eigentlich willst, meist nicht absichtlich in diesen Dateien versteckt ist. Unreal hat ein erstklassiges Lokalisierungssystem, und die meisten ausgelieferten Spiele nutzen es. Deine Aufgabe ist, die Tabelle zu finden, die Strings zu ersetzen und der Engine eine kleine Datei zu geben, die Vorrang vor dem Original hat.
Genau dieser letzte Teil macht Unreal angenehm, sobald man ihn verstanden hat. Du baust kein 60-GB-Spiel neu. Du erzeugst ein Override-Archiv in der Größenordnung von Kilobyte und legst es neben die Originale.
Eines noch vor den Schritten: Die Unreal-Unterstützung in RuneTranslate ist nach bestem Bemühen und neuer als Engines wie RPG Maker oder Ren'Py. Sie wurde auf echten UE4-Titeln als spielbar bestätigt, aber die Formatfläche ist enorm, und jedes Studio packt anders. Verifiziere ein exportiertes Build im Spiel, bevor du dich auf einen langen Übersetzungslauf festlegst.
Was ein Unreal-Spiel tatsächlich ausliefert
Unreal hält spielerseitigen Text in `.locres`-Dateien — der kompilierten Form von FTextLocalizationResource. Es gibt eine pro Kultur, abgelegt auf einem Pfad wie <Game>/Content/Localization/Game/ja/Game.locres, mit Geschwistern für en, zh-Hans und was das Studio sonst ausgeliefert hat. Ein Spiel ganz ohne Übersetzungen hat normalerweise trotzdem eine, für die Kultur, in der es verfasst wurde.
Eine .locres ist keine Textdatei und keine simple Schlüssel/Wert-Liste. Sie ist eine Binärtabelle, organisiert als Namespaces, von denen jeder Keys hält, von denen jeder auf einen String zeigt. In den modernen Versionen werden Namespace und Key als Hashes gespeichert (CRC32 in Version 2, CityHash64 über UTF-16 in Version 3) statt als lesbare Namen, und die Strings selbst leben in einer geteilten, deduplizierten Nachschlagetabelle mit Referenzzählern. Die Laufzeit schlägt einen String nie über seinen englischen Text nach — sie schlägt ihn über dieses Namespace/Key-Paar nach, das zur Build-Zeit in die Blueprints und das C++ des Spiels kompiliert wird.
Diese Struktur diktiert den einzig sicheren Weg, eine solche Datei zu bearbeiten. RuneTranslate bewahrt jeden Namespace-Hash, Key-Hash und Quellstring-Hash Byte für Byte und ändert nur den Wert, baut dann die deduplizierte String-Tabelle und ihre Referenzzähler neu auf. Nichts berechnet einen Hash neu, also kann nichts einen Key erzeugen, den das Spiel nicht findet. Übersetzungen dürfen länger oder kürzer sein als das Original.
Diese .locres-Dateien werden dann in .pak-Archive gepackt — erkennbar an einem Magic-Wert 0x5A6F12E1 in einem Footer ganz am Ende der Datei — oder, bei modernen UE5-Titeln, in IoStore-.utoc/.ucas-Container.
Prüfe den Umfang, bevor du eine Stunde investierst
.locres deckt UI, Menüs, Systemnachrichten, Tutorial-Text, Gegenstands- und Fertigkeitsnamen sowie Untertitel ab — nenn es grob 90 % des sichtbaren Textes in einem typischen Spiel. Das ist der Teil, den RuneTranslate liest und schreibt.
Was es nicht abdeckt: Text, der in DataTables kompiliert oder in cooked `.uasset`-Pakete eingebacken ist. Manche Studios — besonders bei kleineren oder stark Blueprint-getriebenen Projekten — halten Dialoge dort statt im Lokalisierungssystem. Diese Strings sind innerhalb der cooked Pakete hash-adressiert, ohne lesbares Verzeichnis, und sie richtig zu lesen braucht eine .usmap-Mapping-Datei, die das ausgelieferte Spiel nicht enthält. Wenn dein Spiel sein Skript dort hält, kommt die Extraktion mit Menüs und Schaltflächen und ohne jeden Dialog zurück, und RuneTranslate meldet das als ausdrückliches Außerhalb-des-Umfangs-Ergebnis, statt so zu tun, als hätte es geklappt.
Früh zu wissen: Der schnellste Weg zur Prüfung ist, den Schritt zum Anlegen des Projekts laufen zu lassen und anzusehen, was herausgekommen ist. Ein paar hundert kurze Strings, die alle aussehen wie Continue, Options, Are you sure?, heißt: Die UI ist lokalisiert und das Skript nicht. Mehrere tausend Strings inklusive vollständiger Sätze heißt, du bist gut aufgestellt.
Der AES-Schlüssel, und warum er keine Mauer ist
Ein großer Teil ausgelieferter Paks ist AES-256-verschlüsselt — genauer im ECB-Modus ohne IV, angewandt auf den Index des Archivs und oft auf die einzelnen Einträge. Ohne den Schlüssel ist das Archiv undurchsichtig: Du kannst nicht einmal auflisten, was darin ist.
Der Schlüssel ist aus einem simplen Grund wiederherstellbar. Das Spiel muss seine eigenen Archive zur Laufzeit lesen, auf einem Rechner ohne Netz und ohne Lizenzserver, also liegt der Schlüssel als gewöhnliche Daten in der ausgelieferten Binärdatei. RuneTranslate durchsucht die ausführbare Datei und ihre DLLs nach 32-Byte-Fenstern, siebt sie mit einem Entropie-Filter aus (ein echter AES-Schlüssel hat mindestens 25 verschiedene Bytes von 32), macht eine billige Plausibilitätsprüfung, indem es den ersten Block des Index entschlüsselt und fragt, ob sich der führende Wert wie eine plausible String-Länge liest, und verifiziert die Überlebenden dann richtig: den ganzen Index entschlüsseln und seinen SHA-1 gegen den Hash vergleichen, den der Footer des Paks selbst festhält. Dieser letzte Schritt ist der Unterschied zwischen diesem Vorgehen und den Entropie-Ranking-Schlüsselfindern, die herumschwirren — ein Kandidat reproduziert entweder den archiveigenen festgehaltenen Hash, oder er wird verworfen. Ein falscher Schlüssel kann nie akzeptiert werden.
Manche Spiele speichern den Schlüssel als Text statt als rohe Bytes, und manche verteilen ihn über getrennte Instruktionen in der Binärdatei; beide Fälle werden gehandhabt. Wenn nichts davon greift, nimmt der Neues-Projekt-Dialog einen eingefügten Schlüssel in Hex (0x… oder 64 Hex-Zeichen) oder Base64, und einmal wiederhergestellt, wird der Schlüssel pro Projekt zwischengespeichert, sodass du nicht bei jedem Export eine 85-MB-Binärdatei neu durchsuchst.
UE5-IoStore ist anders, und die Extraktion ist gezielt
UE5-Titel liefern zunehmend IoStore-Container statt schlichter Paks aus: ein .utoc-Verzeichnis, gepaart mit einem .ucas-Daten-Blob, mit Oodle-Kompression und eigener Verschlüsselung. Ein naiver Ansatz wäre, das Ganze auszupacken, was bei einem 105-GB-Spiel gar kein Ansatz ist.
RuneTranslate bündelt retoc (MIT-lizenziert) und bittet es, die Container in ein Legacy-Pak zu konvertieren, gefiltert auf ausschließlich die Lokalisierungsdateien — das Äquivalent von to-legacy -f locres --no-shaders --no-script-objects. Ein 105-GB-IoStore-Titel filtert sich auf ein paar Kilobyte .locres herunter, in Sekunden statt Stunden. retoc handhabt außerdem das AES und Oodle des Containers, weshalb IoStore-Spiele das Oodle-Problem umgehen, in das lose Paks laufen können.
Die wichtige Hälfte davon ist, dass IoStore nur das Lesen verkompliziert. Das Schreiben ist universell, und das ist der nächste Abschnitt.
Die Ausgabe ist ein Override-Pak, kein neu gebautes Spiel
Das ist der Teil, den keine konkurrierende Anleitung richtig erklärt, und er ist der Grund, warum das Übersetzen von Unreal günstig ist, sobald es überhaupt funktioniert.
Unreal mountet Pak-Dateien in einer definierten Reihenfolge, und jedes Archiv, dessen Name auf `_P` endet, wird zuletzt gemountet. Spätere Mounts gewinnen. Ein kleines Archiv, das nichts als deine geänderte .locres enthält, auf demselben virtuellen Pfad, den das Basisspiel nutzt, überschattet also schlicht das Original — der Lokalisierungsmanager lädt deins und sieht das ausgelieferte nie.
- Kein Neu-Signieren. Pak-Signierung ist ein vollständig separater RSA-Mechanismus und wird in ausgelieferten Consumer-Titeln selten erzwungen; das Override rührt sie nicht an.
- Kein AES-Schlüssel für die Ausgabe nötig. Das Override wird unverschlüsselt und unkomprimiert geschrieben. Der Schlüssel wurde immer nur zum Lesen des Originals gebraucht.
- Kein Neupacken des Spiels. Die Basisarchive bleiben unangetastet. Eine 60-GB-Installation bleibt 60 GB; deine Übersetzung ist eine Datei in der Größenordnung von Kilobyte.
- Es funktioniert auch für IoStore-Spiele.
.locreswird über das Pak-Dateisystem gelesen und nicht über den Zen-Package-Loader, sodass ein schlichtes loses_P.pakselbst von einem UE5-Spiel aufgegriffen wird, dessen Assets alle in.utoc/.ucasliegen.
Du installierst es, indem du das erzeugte _P.pak nach <Game>/Content/Paks/ kopierst — denselben Ordner, in dem die Originale liegen. Manche Spiele mounten zusätzlich einen ~mods/-Unterordner, was genauso gut funktioniert. Die Übersetzung zu entfernen heißt, diese eine Datei zu löschen, was ein Zurückrollen trivial macht und es sicher macht, früh zu testen.
Die Schritte
- Installiere RuneTranslate von der Download-Seite und melde dich an. Beim ersten Start ist eine kostenlose Patreon-Anmeldung nötig; die kostenlose Stufe schaltet jede Engine und jeden Anbieter frei — sie drosselt den Durchsatz und hält ein Projekt zur Zeit.
- Lege ein neues Projekt an und richte es auf den Wurzelordner des Spiels — den mit der ausführbaren Datei und dem
<Game>-Verzeichnis. Die Erkennung sucht nachContent/Paksund der Footer-Magic des Paks oder nach.utoc/.ucas. - Wenn die Archive verschlüsselt sind, lass die Schlüsselwiederherstellung laufen. Sie durchsucht die ausgelieferten Binärdateien und verifiziert jeden Kandidaten gegen den Index-Hash des Paks selbst. Wenn sie leer ausgeht, füge einen Schlüssel in den Dialog ein.
- Lass die Extraktion durchlaufen. Du bekommst die
.locres-Einträge für die Ausgangskultur, gruppiert nach Lokalisierungsziel, bereit zur Durchsicht. - Wähle einen Anbieter und übersetze. Kurze UI-Strings und lange Dialoge lassen sich an unterschiedliche Anbieter routen, wenn du nur dort Geld ausgeben willst, wo es zählt.
- Prüfe, was zurückkam. Menü-Strings sind die Stelle, an der maschinelle Übersetzung am schwächsten ist — ein blankes
SaveoderLoadhat keinen Kontext, und eine Zwei-Wort-Schaltfläche, die als Satz zurückkommt, läuft über ihr Widget hinaus. - Exportiere. RuneTranslate schreibt ein einzelnes unverschlüsseltes
_P.pak, das deine geänderte.locresam korrekten engine-relativen Pfad enthält. - Kopiere diese Datei nach
<Game>/Content/Paks/und starte das Spiel.
Teste nach Schritt 8 mit einer Handvoll übersetzter Strings, bevor du das ganze Spiel durch einen Anbieter schickst. Wenn das Override ignoriert werden wird — falscher Ordner, falsche Kultur, ungewöhnliches Mount-Setup —, willst du das in fünf Minuten herausfinden und nicht, nachdem du für 9.000 Strings bezahlt hast.
Platzhalter und Rich Text
Unreals FText-Formatierung nutzt {0}, {1} für positionale Argumente und {PlayerName}, {Count} für benannte, dazu <RichText>-Markup mit </>-Schließern für Inline-Stilisierung. Wenn ein Übersetzungsanbieter eines davon weglässt oder verstümmelt, zeigt das Spiel keinen leicht falschen Satz — es zeigt einen kaputten Formatstring, oder das Argument verschwindet still aus der Zeile.
RuneTranslate maskiert jedes einzelne davon in einen neutralen Platzhalter, bevor der Anbieter den String sieht, und stellt sie danach wieder her. Der Anbieter übersetzt um die Marker herum statt durch sie hindurch, sodass ein Argument nicht von einem Modell gelöscht werden kann, das die geschweiften Klammern für einen Tippfehler hielt. Wenn du weiter gehen und bestimmte Strings ganz von der Übersetzung zurückhalten willst, funktionieren Regex-Ausschlussfilter auf jeder Engine, und ein Glossar hält Eigennamen im ganzen Spiel stabil.
Die Akzent-Falle, die ein Kodierungsfehler ist und keine Schrift
Diese lohnt eine eigene Dokumentation, weil das Symptom genau in die falsche Richtung zeigt. Unreal serialisiert einen String mit einem Längenpräfix: Eine positive Länge bedeutet ein Byte pro Zeichen, eine negative Länge bedeutet UTF-16. Die Engine wählt die schmale Form nur dann, wenn jedes Zeichen 7-Bit-ASCII ist — ihre Prüfung weist alles oberhalb von 0x7F zurück. Ihr Loader ist genauso gebaut, sodass er, wenn ihm ein schmaler String mit einem hohen Byte übergeben wird, für jedes davon ein buchstäbliches ? einsetzt.
Die praktische Folge: Eine Übersetzung mit poción mágica, in der schmalen Form geschrieben, erreicht den Spieler als poci?n m?gica. Und das betroffene Band ist U+0080–U+00FF, was genau die Akzentbuchstaben des Spanischen, Französischen, Deutschen, Portugiesischen, Italienischen und der nordischen Sprachen sind. Polnisch, Türkisch, Tschechisch, Griechisch, Kyrillisch, Japanisch und Chinesisch liegen alle oberhalb von U+00FF, nehmen automatisch den breiten Zweig und sind nie betroffen.
Der Fingerabdruck ist also: Akzente brechen im Spanischen, aber Russisch ist in Ordnung. Wenn du das siehst, ist es ein Kodierungsfehler in dem, was die Datei geschrieben hat, und keine fehlende Glyphe in der Schrift des Spiels — eine fehlende Glyphe rendert als Kästchen oder als gar nichts, nie als Fragezeichen. RuneTranslate hatte exakt diesen Fehler und hat ihn in 0.49.4 behoben; der Encoder lebt jetzt an einer Stelle und schreibt die breite Form für alles außerhalb von ASCII. Es lohnt sich, davon zu wissen, weil andere Werkzeuge in diesem Feld es weiterhin falsch machen.
Einen Anbieter wählen
Drei der neun Anbieter brauchen überhaupt keinen API-Schlüssel — Google, das kostenlose DeepL und DeepLs Classic-/Next-gen-Modelle — und die kostenlose Stufe gibt dir alle drei. Für ein Spiel, das größtenteils UI ist, ist ein kostenloser Anbieter wirklich in Ordnung. Für dialoglastige Titel handhabt ein LLM-Anbieter den Kontext weit besser; OpenAI, Anthropic, DeepSeek, jeder OpenAI-kompatible Endpunkt und ein lokales Modell über Ollama oder LM Studio stehen alle zur Verfügung. Der Anbieter-Vergleich geht durch, worin jeder gut und schlecht ist, mit echten Kostenzahlen.
Fehlerbehebung
Das Spiel läuft, aber nichts ist übersetzt
Fast immer eines von drei Dingen. Die Datei liegt nicht in <Game>/Content/Paks/ — sie neben die ausführbare Datei zu legen, tut nichts. Der Dateiname hat sein _P-Suffix verloren, dann mountet sie in gewöhnlicher alphabetischer Reihenfolge und das Basis-Pak gewinnt womöglich. Oder das Spiel läuft in einer Kultur, die du nicht übersetzt hast: Es lädt die .locres für die Kultur, die es beim Start aufgelöst hat, sodass ein Spiel, das en erzwingt, ein Override ignoriert, das nur für ja geschrieben wurde. Prüfe zuerst die Spracheinstellung des Spiels.
Die Extraktion scheitert an einem Oodle-komprimierten losen Pak
Ein loses .pak, das mit Oodle komprimiert ist, braucht einen Dekompressor, der nicht mitgeliefert werden kann. Wenn das Spiel auch IoStore-Container ausliefert, handhabt der retoc-Pfad Oodle, und du bist fein raus. Wenn es nur lose Paks sind, ist das vorerst ein hartes Ende, ausdrücklich gemeldet statt als stilles leeres Ergebnis.
Das Spiel hat nirgends eine .locres
Dann ist sein Text in cooked Assets kompiliert, und dieser Weg erreicht ihn nicht. Das klarste Beispiel ist ein großer Live-Service-UE5-Titel, dessen IoStore-Index auf Content-Hashes ohne jeden Dateinamen reduziert ist — hunderttausende Chunks und null .locres. RuneTranslate sagt das, statt sich durch den vollständigen Container zu mahlen.
Die Erkennung greift überhaupt nicht
Richte es auf den Ordner mit der ausführbaren Datei, nicht auf Content/Paks selbst und nicht auf einen übergeordneten Ordner voller anderer Spiele. Wenn es dann immer noch nicht erkennt, ist die Verpackung ungewöhnlich und eine Meldung wert — das Pak-Format hat versionsspezifische Footer-Layouts, und ein Dialekt, den noch niemand gesehen hat, ist genau die Art Sache, die ergänzt wird.
Ehrliche Grenzen
Die Unreal-Unterstützung ist nach bestem Bemühen. .locres in losen und verschlüsselten Paks sowie in UE5-IoStore ist der bewährte Pfad, im Spiel auf einem UE4-Titel auf Spanisch als spielbar bestätigt. Text in DataTables und in cooked .uasset wird nicht abgedeckt. Oodle-komprimierte lose Paks ohne IoStore-Gegenstück werden nicht unterstützt. Paks mit erzwungener Signierung lassen sich nicht überschreiben, sind in der Praxis aber selten. Und weil das Format zwischen Engine-Versionen und Studios so stark variiert, behandle den ersten Export als Test und nicht als Endergebnis.
Was am Ende herauskommt, ist ein spielbares übersetztes Build, das du auf deinem eigenen Rechner behältst: das Originalspiel unangetastet, dazu eine kleine Datei, die du löschen kannst, um alles rückgängig zu machen. Wenn du Engines vergleichst oder prüfst, ob dein Spiel überhaupt abgedeckt ist, hat die Unreal-Engine-Seite die technischen Details, und alle Engines listet die siebzehn unterstützten Formate, darunter Unity und RPG Maker. Wenn du neu im ganzen Prozess bist, fang mit der allgemeinen Anleitung an und komm für die Unreal-spezifischen Teile hierher zurück.
Bereit, RuneTranslate auszuprobieren?
Der Free-Tarif schaltet jede Engine + jeden Übersetzungsanbieter frei. Supporter ($3/Mon.) schaltet volle Geschwindigkeit frei.
Für Windows herunterladen
