Comment traduire les jeux Unreal Engine
Les jeux Unreal livrent leur texte dans des tables .locres compilées, à l'intérieur de conteneurs .pak ou IoStore. Voici comment les lire, et pourquoi la sortie est un minuscule pak de surcharge plutôt qu'un jeu reconstruit.
Un jeu Unreal Engine ressemble à la chose la plus difficile à traduire sur votre disque. Pas de dossier data, pas de fichiers de script, aucun .json à ouvrir — juste un exécutable, un répertoire Content/Paks contenant un ou deux .pak énormes, et peut-être une paire de conteneurs .utoc/.ucas. La bonne nouvelle, c'est que le texte qui vous intéresse n'est en général pas caché dans ces fichiers par conception. Unreal dispose d'un système de localisation de premier plan, et la plupart des jeux publiés l'utilisent. Votre travail consiste à trouver la table, remplacer les chaînes, et remettre au moteur un petit fichier qui prend le pas sur l'original.
C'est cette dernière partie qui rend Unreal agréable une fois comprise. Vous ne reconstruisez pas un jeu de 60 Go. Vous produisez une archive de surcharge qui se mesure en kilo-octets et vous la déposez à côté des originaux.
Une chose avant les étapes : la prise en charge d'Unreal dans RuneTranslate est au mieux, et plus récente que celle de moteurs comme RPG Maker ou Ren'Py. Elle a été confirmée jouable sur de vrais titres UE4, mais la surface du format est énorme et chaque studio empaquette différemment. Vérifiez un build exporté en jeu avant de vous engager dans une longue passe de traduction.
Ce qu'un jeu Unreal livre réellement
Unreal garde le texte destiné au joueur dans des fichiers `.locres` — la forme compilée de FTextLocalizationResource. Il y en a un par culture, sur un chemin du type <Game>/Content/Localization/Game/ja/Game.locres, avec des voisins pour en, zh-Hans et ce que le studio a livré d'autre. Un jeu sans aucune traduction en a normalement quand même un, pour la culture dans laquelle il a été écrit.
Un .locres n'est ni un fichier texte ni une simple liste clé/valeur. C'est une table binaire organisée en namespaces, chacun contenant des clés, chaque clé pointant vers une chaîne. Dans les versions modernes, le namespace et la clé sont stockés sous forme de hachages (CRC32 en version 2, CityHash64 sur de l'UTF-16 en version 3) plutôt que sous forme de noms lisibles, et les chaînes elles-mêmes vivent dans une table de recherche partagée et dédupliquée, avec des compteurs de références. Le moteur ne cherche jamais une chaîne par son texte anglais — il la cherche par cette paire namespace/clé, compilée dans les Blueprints et le C++ du jeu au moment du build.
Cette structure dicte la seule façon sûre d'en modifier un. RuneTranslate préserve chaque hachage de namespace, de clé et de chaîne source octet pour octet et ne change que la valeur, puis reconstruit la table de chaînes dédupliquée et ses compteurs de références. Rien ne recalcule un hachage, donc rien ne peut produire une clé que le jeu ne retrouve pas. Les traductions sont libres d'être plus longues ou plus courtes que l'original.
Ces fichiers .locres sont ensuite empaquetés dans des archives .pak — identifiées par la valeur magique 0x5A6F12E1 dans un pied de fichier tout à la fin — ou, sur les titres UE5 modernes, dans des conteneurs IoStore .utoc/.ucas.
Vérifiez le périmètre avant d'y passer une heure
Le .locres couvre l'interface, les menus, les messages système, les textes de tutoriel, les noms d'objets et de compétences, et les sous-titres — disons à peu près 90 % du texte visible d'un jeu type. C'est la partie que RuneTranslate lit et écrit.
Ce qu'il ne couvre pas : le texte compilé dans des DataTables ou incrusté dans des paquets `.uasset` cuits. Certains studios — en particulier sur des projets plus petits ou fortement pilotés par Blueprint — y gardent leurs dialogues au lieu de passer par le système de localisation. Ces chaînes sont adressées par hachage à l'intérieur de paquets cuits, sans index de répertoire lisible, et les lire correctement demande un fichier de correspondance .usmap que le jeu publié n'inclut pas. Si votre jeu y garde son script, l'extraction reviendra avec des menus et des boutons et aucun dialogue, et RuneTranslate le signale comme un résultat explicitement hors périmètre plutôt que de faire semblant d'avoir réussi.
Bon à savoir tôt : le moyen le plus rapide de vérifier est de lancer l'étape de création du projet et de regarder ce qui en sort. Quelques centaines de chaînes courtes qui ressemblent toutes à Continue, Options, Are you sure? veulent dire que l'interface est localisée mais pas le script. Plusieurs milliers de chaînes comprenant des phrases entières veulent dire que vous êtes en bonne posture.
La clé AES, et pourquoi ce n'est pas un mur
Une grande partie des paks publiés sont chiffrés en AES-256 — précisément en mode ECB sans IV, appliqué à l'index de l'archive et souvent aux entrées individuelles. Sans la clé, l'archive est opaque : vous ne pouvez même pas lister ce qu'elle contient.
La clé est récupérable pour une raison simple. Le jeu doit lire ses propres archives à l'exécution, sur une machine sans réseau et sans serveur de licence, donc la clé est présente dans le binaire publié comme une donnée ordinaire. RuneTranslate parcourt l'exécutable et ses DLL à la recherche de fenêtres de 32 octets, les élague avec un filtre d'entropie (une vraie clé AES a au moins 25 octets distincts sur 32), fait une vérification rapide en déchiffrant le premier bloc de l'index et en se demandant si la valeur de tête ressemble à une longueur de chaîne plausible, puis vérifie proprement les survivants : déchiffrer l'index entier et comparer son SHA-1 au hachage que le pied du pak enregistre lui-même. C'est cette dernière étape qui fait la différence avec les chercheurs de clés par classement d'entropie qui circulent — un candidat reproduit le hachage enregistré par l'archive, ou il est rejeté. Une mauvaise clé ne peut jamais être acceptée.
Certains jeux stockent la clé sous forme de texte plutôt que d'octets bruts, et certains la répartissent sur plusieurs instructions du binaire ; les deux cas sont gérés. Si rien de tout cela n'aboutit, la fenêtre Nouveau projet accepte une clé collée en hexadécimal (0x… ou 64 caractères hex) ou en base64, et une fois récupérée la clé est mise en cache par projet, pour que vous ne rescanniez pas un exécutable de 85 Mo à chaque export.
L'IoStore d'UE5 est différent, et l'extraction est ciblée
Les titres UE5 livrent de plus en plus des conteneurs IoStore au lieu de paks simples : un répertoire .utoc associé à un blob de données .ucas, avec la compression Oodle et son propre chiffrement. L'approche naïve ici consiste à tout déballer, ce qui sur un jeu de 105 Go n'est pas une approche du tout.
RuneTranslate embarque retoc (sous licence MIT) et lui demande de convertir les conteneurs en pak legacy filtré aux seuls fichiers de localisation — l'équivalent de to-legacy -f locres --no-shaders --no-script-objects. Un titre IoStore de 105 Go se réduit à quelques kilo-octets de .locres, en quelques secondes plutôt qu'en quelques heures. retoc gère aussi l'AES et l'Oodle propres au conteneur, et c'est pourquoi les jeux IoStore contournent le problème Oodle que les paks en vrac peuvent rencontrer.
La moitié importante de tout cela, c'est que l'IoStore ne complique que la lecture. L'écriture est universelle, et c'est la section suivante.
La sortie est un pak de surcharge, pas un jeu reconstruit
C'est la partie qu'aucun guide concurrent n'explique correctement, et c'est la raison pour laquelle traduire de l'Unreal coûte peu dès que cela fonctionne.
Unreal monte les fichiers pak dans un ordre défini, et toute archive dont le nom se termine par `_P` est montée en dernier. Les montages tardifs l'emportent. Une petite archive ne contenant rien d'autre que votre .locres modifié, au même chemin virtuel que celui utilisé par le jeu de base, masque donc tout simplement l'original — le gestionnaire de localisation charge le vôtre et ne voit jamais celui qui a été livré.
- Aucune re-signature. La signature des paks est un mécanisme RSA entièrement distinct, rarement imposé dans les titres grand public publiés ; la surcharge n'y touche pas.
- Aucune clé AES nécessaire pour la sortie. La surcharge est écrite non chiffrée et non compressée. La clé n'a jamais servi qu'à lire l'original.
- Aucun ré-empaquetage du jeu. Les archives de base ne sont pas touchées. Une installation de 60 Go reste à 60 Go ; votre traduction est un fichier qui se mesure en kilo-octets.
- Cela marche aussi pour les jeux IoStore. Le
.locresest lu via le système de fichiers pak plutôt que par le chargeur de paquets Zen, si bien qu'un simple_P.paken vrac est pris en compte même par un jeu UE5 dont tous les assets vivent dans des.utoc/.ucas.
Vous l'installez en copiant le _P.pak produit dans <Game>/Content/Paks/ — le dossier même où se trouvent les originaux. Certains jeux montent aussi un sous-dossier ~mods/, qui fonctionne tout aussi bien. Retirer la traduction revient à supprimer ce seul fichier, ce qui rend le retour en arrière trivial et permet de tester tôt sans risque.
Les étapes
- Installez RuneTranslate depuis la page de téléchargement et connectez-vous. Une connexion Patreon gratuite est requise au premier lancement ; le palier gratuit débloque chaque moteur et chaque fournisseur — il bride le débit et ne garde qu'un projet à la fois.
- Créez un projet et pointez-le vers le dossier racine du jeu — celui qui contient l'exécutable et le répertoire
<Game>. La détection chercheContent/Pakset la valeur magique du pied de pak, ou des.utoc/.ucas. - Si les archives sont chiffrées, laissez la récupération de clé s'exécuter. Elle parcourt les binaires publiés et vérifie chaque candidat contre le hachage d'index du pak lui-même. Si elle ne trouve rien, collez une clé dans la fenêtre.
- Laissez l'extraction se terminer. Vous obtenez les entrées
.locresde la culture source, regroupées par cible de localisation, prêtes à relire. - Choisissez un fournisseur et traduisez. Les courtes chaînes d'interface et les longs dialogues peuvent être routés vers des fournisseurs différents si vous voulez ne dépenser que là où cela compte.
- Relisez ce qui est revenu. Les chaînes de menu sont là où la traduction automatique est la plus faible — un
Saveou unLoadisolé n'a aucun contexte, et un bouton de deux mots qui revient sous forme de phrase débordera de son widget. - Exportez. RuneTranslate écrit un unique
_P.paknon chiffré contenant votre.locresmodifié, au bon chemin relatif au moteur. - Copiez ce fichier dans
<Game>/Content/Paks/et lancez le jeu.
Faites le test de l'étape 8 avec une poignée de chaînes traduites, avant de faire passer tout le jeu chez un fournisseur. Si la surcharge doit être ignorée — mauvais dossier, mauvaise culture, montage inhabituel — vous voulez le découvrir en cinq minutes, pas après avoir payé pour 9 000 chaînes.
Espaces réservés et texte enrichi
Le formatage FText d'Unreal utilise {0}, {1} pour les arguments positionnels et {PlayerName}, {Count} pour les arguments nommés, plus le balisage <RichText> avec ses fermetures </> pour la mise en forme en ligne. Si un fournisseur de traduction en supprime ou en abîme un, le jeu n'affiche pas une phrase légèrement fausse — il affiche une chaîne de format cassée, ou l'argument disparaît silencieusement de la ligne.
RuneTranslate masque chacun d'eux derrière un espace réservé neutre avant que le fournisseur ne voie la chaîne, et les restaure ensuite. Le fournisseur traduit autour des marqueurs plutôt qu'à travers, si bien qu'un argument ne peut pas être supprimé par un modèle qui a décidé que les accolades ressemblaient à une faute de frappe. Si vous voulez aller plus loin et retenir certaines chaînes entièrement hors de la traduction, les filtres d'exclusion regex fonctionnent sur tous les moteurs, et un glossaire garde les noms propres stables dans tout le jeu.
Le piège des accents, qui est un bug d'encodage et non une police
Celui-ci mérite d'être documenté à part, parce que le symptôme pointe exactement dans la mauvaise direction. Unreal sérialise une chaîne avec un préfixe de longueur : une longueur positive signifie un octet par caractère, une longueur négative signifie de l'UTF-16. Le moteur ne choisit la forme étroite que lorsque chaque caractère est de l'ASCII 7 bits — son test rejette tout ce qui dépasse 0x7F. Son chargeur est construit de la même manière, donc si on lui remet une chaîne étroite contenant un octet haut, il substitue un ? littéral à chacun.
La conséquence pratique : une traduction contenant poción mágica écrite sous la forme étroite arrive chez le joueur en poci?n m?gica. Et la plage concernée est U+0080–U+00FF, c'est-à-dire précisément les lettres accentuées de l'espagnol, du français, de l'allemand, du portugais, de l'italien et des langues nordiques. Le polonais, le turc, le tchèque, le grec, le cyrillique, le japonais et le chinois sont tous au-dessus de U+00FF, prennent automatiquement la branche large, et ne sont jamais touchés.
L'empreinte est donc : les accents cassent en espagnol mais le russe va bien. Si vous voyez cela, c'est un bug d'encodage dans ce qui a écrit le fichier, pas un glyphe manquant dans la police du jeu — un glyphe manquant s'affiche en carré ou en rien du tout, jamais en point d'interrogation. RuneTranslate a eu exactement ce bug et l'a corrigé en 0.49.4 ; l'encodeur vit désormais à un seul endroit et écrit la forme large pour tout ce qui sort de l'ASCII. Cela vaut la peine d'être connu, parce que d'autres outils du domaine se trompent encore là-dessus.
Choisir un fournisseur
Trois des neuf fournisseurs ne demandent aucune clé d'API — Google, DeepL gratuit, et les modèles Classic / Next-gen de DeepL — et le palier gratuit vous les donne tous. Pour un jeu essentiellement fait d'interface, un fournisseur gratuit convient parfaitement. Pour les titres riches en dialogues, un fournisseur LLM gère bien mieux le contexte ; OpenAI, Anthropic, DeepSeek, tout point d'accès compatible OpenAI, et un modèle local via Ollama ou LM Studio sont tous disponibles. La comparaison des fournisseurs passe en revue ce que chacun fait bien ou mal, avec de vrais chiffres de coût.
Dépannage
Le jeu se lance mais rien n'est traduit
Presque toujours l'une de trois choses. Le fichier n'est pas dans <Game>/Content/Paks/ — le poser à côté de l'exécutable ne fait rien. Le nom de fichier a perdu son suffixe _P, auquel cas il se monte dans l'ordre alphabétique ordinaire et le pak de base peut l'emporter. Ou le jeu tourne dans une culture que vous n'avez pas traduite : il charge le .locres de la culture qu'il a résolue au démarrage, si bien qu'un jeu forçant en ignorera une surcharge écrite uniquement pour ja. Vérifiez d'abord le réglage de langue du jeu.
L'extraction échoue sur un pak en vrac compressé en Oodle
Un .pak en vrac compressé en Oodle demande un décompresseur qui ne peut pas être embarqué. Si le jeu livre aussi des conteneurs IoStore, la route retoc gère l'Oodle et tout va bien. S'il n'y a que des paks en vrac, c'est un arrêt net pour l'instant, signalé explicitement plutôt que sous forme de résultat vide silencieux.
Le jeu n'a aucun .locres nulle part
Alors son texte est compilé dans des assets cuits, et cette voie ne l'atteint pas. L'exemple le plus net est un gros titre UE5 en service continu dont l'index IoStore est réduit à des hachages de contenu, sans aucun nom de fichier — des centaines de milliers de morceaux et zéro .locres. RuneTranslate le dit au lieu de moudre le conteneur entier.
La détection ne se déclenche pas du tout
Pointez vers le dossier contenant l'exécutable, pas vers Content/Paks lui-même ni vers un dossier parent plein d'autres jeux. Si la détection ne se fait toujours pas, l'empaquetage est inhabituel et vaut la peine d'être signalé — le format pak a des dispositions de pied spécifiques à chaque version, et un dialecte que personne n'a encore vu est exactement le genre de chose qui finit par être ajouté.
Limites honnêtes
La prise en charge d'Unreal est au mieux. Le .locres dans des paks en vrac et chiffrés, et dans l'IoStore d'UE5, est la voie éprouvée, confirmée jouable en jeu sur un titre UE4 en espagnol. Le texte des DataTables et des .uasset cuits n'est pas couvert. Les paks en vrac compressés en Oodle sans contrepartie IoStore ne sont pas pris en charge. Les paks à signature imposée ne peuvent pas être surchargés, même s'ils sont rares en pratique. Et comme le format varie énormément d'une version de moteur et d'un studio à l'autre, traitez le premier export comme un test plutôt que comme le livrable.
Ce que vous obtenez au bout est un build traduit jouable que vous gardez sur votre propre machine : le jeu d'origine intact, plus un petit fichier que vous pouvez supprimer pour tout annuler. Si vous comparez les moteurs ou vérifiez si votre jeu est couvert, la page moteur Unreal donne le détail technique et tous les moteurs liste les dix-sept formats pris en charge, dont Unity et RPG Maker. Si vous découvrez tout le processus, commencez par le guide général et revenez ici pour les parties propres à Unreal.
Prêt à essayer RuneTranslate ?
L'offre gratuite débloque tous les moteurs et tous les fournisseurs de traduction. Supporter (3 $/mois) débloque la vitesse maximale.
Télécharger pour Windows
