Unreal Engine oyunları nasıl çevrilir
Unreal oyunları metnini .pak veya IoStore kapsayıcılarının içindeki derlenmiş .locres tablolarında gönderir. Bunları nasıl okuyacağınız ve çıktının neden yeniden inşa edilmiş bir oyun değil, küçücük bir geçersiz kılma pak’ı olduğu burada.
Bir Unreal Engine oyunu, sürücünüzdeki çevrilmesi en zor şey gibi görünür. Ne bir data klasörü var, ne betik dosyaları, ne de açabileceğiniz bir .json — yalnızca bir yürütülebilir dosya, bir ya da iki devasa .pak dosyası tutan bir Content/Paks dizini ve belki bir çift .utoc/.ucas kapsayıcısı. İyi haber şu ki asıl istediğiniz metin genellikle tasarım gereği o dosyaların içine gizlenmiş değildir. Unreal’ın birinci sınıf bir yerelleştirme sistemi vardır ve gönderilen oyunların çoğu onu kullanır. Sizin işiniz tabloyu bulmak, dizeleri değiştirmek ve motora orijinalin önüne geçen küçük bir dosya vermektir.
İşte bu son kısım, anladığınızda Unreal’ı keyifli kılan şeydir. 60 GB’lık bir oyunu yeniden inşa etmezsiniz. Kilobaytlarla ölçülen bir geçersiz kılma arşivi üretir ve onu orijinallerin yanına bırakırsınız.
Adımlardan önce bir not: RuneTranslate’teki Unreal desteği en iyi çabadır ve RPG Maker ya da Ren’Py gibi motorlardan daha yenidir. Gerçek UE4 oyunlarında oynanabilir olduğu doğrulandı, ama format yüzeyi devasa ve her stüdyo farklı paketliyor. Uzun bir çeviri çalışmasına girişmeden önce dışa aktarılan sürümü oyun içinde doğrulayın.
Bir Unreal oyunu gerçekte ne gönderir
Unreal, oyuncuya dönük metni `.locres` dosyalarında tutar — FTextLocalizationResource’un derlenmiş biçimi. Kültür başına bir tane vardır ve <Game>/Content/Localization/Game/ja/Game.locres gibi bir yolda durur; en, zh-Hans ve stüdyonun gönderdiği başka ne varsa onların kardeşleri de yanındadır. Hiç çevirisi olmayan bir oyunda bile normalde bir tane bulunur: yazıldığı kültür için.
Bir .locres ne bir metin dosyasıdır ne de basit bir anahtar/değer listesi. Her biri anahtarlar tutan namespace’ler hâlinde düzenlenmiş ikili bir tablodur ve her anahtar bir dizeyi gösterir. Modern sürümlerde namespace ve anahtar, okunabilir adlar yerine hash olarak saklanır (sürüm 2’de CRC32, sürüm 3’te UTF-16 üzerinde CityHash64) ve dizelerin kendisi de referans sayaçlarıyla birlikte paylaşılan, tekilleştirilmiş bir arama tablosunda yaşar. Çalışma zamanı bir dizeyi asla İngilizce metnine göre aramaz — derleme sırasında oyunun Blueprint’lerine ve C++’ına gömülen o namespace/anahtar çiftine göre arar.
Bu yapı, böyle bir dosyayı düzenlemenin tek güvenli yolunu da dayatır. RuneTranslate her namespace hash’ini, anahtar hash’ini ve kaynak-dize hash’ini bayt bayt korur ve yalnızca değeri değiştirir, ardından tekilleştirilmiş dize tablosunu ve referans sayaçlarını yeniden kurar. Hiçbir hash yeniden hesaplanmaz, dolayısıyla oyunun bulamayacağı bir anahtar üretilemez. Çeviriler orijinalden uzun ya da kısa olmakta serbesttir.
Bu .locres dosyaları sonra .pak arşivlerine paketlenir — dosyanın en sonundaki bir alt bilgide yer alan 0x5A6F12E1 sihirli değeriyle tanınır — ya da modern UE5 oyunlarında IoStore .utoc/.ucas kapsayıcılarına.
Bir saat harcamadan önce kapsamı kontrol edin
.locres; arayüzü, menüleri, sistem mesajlarını, eğitim metnini, eşya ve beceri adlarını ve altyazıları kapsar — tipik bir oyunda görünür metnin kabaca %90’ı diyelim. RuneTranslate’in okuyup yazdığı kısım budur.
Kapsamadığı şey: DataTable’lara derlenmiş ya da pişirilmiş `.uasset` paketlerinin içine gömülmüş metin. Bazı stüdyolar — özellikle daha küçük veya ağırlıklı Blueprint ile kurulmuş projelerde — diyalogu yerelleştirme sistemi yerine orada tutar. O dizeler, pişirilmiş paketlerin içinde okunabilir bir dizin olmadan hash ile adreslenir ve düzgün okunmaları, gönderilen oyunun içermediği bir .usmap eşleme dosyası gerektirir. Oyununuz betiğini orada tutuyorsa, çıkarma menüler ve düğmelerle, hiç diyalog olmadan geri döner — ve RuneTranslate bunu başarılı olmuş gibi göstermek yerine açıkça kapsam dışı bir sonuç olarak bildirir.
Erkenden bilmekte fayda var: kontrol etmenin en hızlı yolu proje oluşturma adımını çalıştırıp ne çıktığına bakmaktır. Hepsi Continue, Options, Are you sure? gibi görünen birkaç yüz kısa dize, arayüzün yerelleştirildiği ama betiğin yerelleştirilmediği anlamına gelir. Tam cümleler dahil birkaç bin dize ise işinizin yolunda olduğunu gösterir.
AES anahtarı ve neden bir duvar olmadığı
Gönderilen pak’ların büyük bir kısmı AES-256 şifrelidir — özellikle IV’süz ECB kipinde, arşivin dizinine ve sıklıkla tek tek girişlerine uygulanmış. Anahtar olmadan arşiv opaktır: içinde ne olduğunu listeleyemezsiniz bile.
Anahtarın kurtarılabilir olmasının basit bir nedeni var. Oyun kendi arşivlerini çalışma zamanında, ağı ve lisans sunucusu olmayan bir makinede okumak zorundadır, dolayısıyla anahtar gönderilen ikilinin içinde sıradan veri olarak bulunur. RuneTranslate yürütülebilir dosyayı ve DLL’lerini 32 baytlık pencereler için tarar, bunları bir entropi filtresiyle eler (gerçek bir AES anahtarında 32 bayttan en az 25’i farklıdır), dizinin ilk bloğunu çözüp baştaki değerin makul bir dize uzunluğu gibi okunup okunmadığına bakarak ucuz bir akıl sağlığı kontrolü yapar ve ardından hayatta kalanları düzgünce doğrular: dizinin tamamını çözer ve SHA-1’ini pak’ın kendi alt bilgisinde kayıtlı hash ile karşılaştırır. Bu son adım, ortalıkta dolaşan entropiye göre sıralayan anahtar bulucularla arasındaki farktır — bir aday ya arşivin kendi kayıtlı hash’ini yeniden üretir ya da reddedilir. Yanlış bir anahtar asla kabul edilemez.
Bazı oyunlar anahtarı ham bayt yerine metin olarak saklar, bazıları da ikilide ayrı komutlara böler; her iki durum da işlenir. Hiçbiri işe yaramazsa, Yeni Proje iletişim kutusu onaltılık (0x… ya da 64 onaltılık karakter) veya base64 olarak yapıştırdığınız bir anahtarı kabul eder; anahtar bir kez kurtarıldıktan sonra proje başına önbelleğe alınır, böylece her dışa aktarımda 85 MB’lık bir yürütülebilir dosyayı yeniden taramazsınız.
UE5 IoStore farklıdır ve çıkarma hedeflidir
UE5 oyunları giderek daha çok düz pak yerine IoStore kapsayıcıları gönderiyor: bir .ucas veri blobuyla eşleşen bir .utoc dizini, Oodle sıkıştırması ve kendi şifrelemesiyle. Buradaki naif yaklaşım her şeyi açmaktır, ki 105 GB’lık bir oyunda bu zaten bir yaklaşım değildir.
RuneTranslate retoc’u (MIT lisanslı) paketler ve ondan kapsayıcıları yalnızca yerelleştirme dosyalarıyla sınırlanmış eski tip bir pak’a dönüştürmesini ister — to-legacy -f locres --no-shaders --no-script-objects karşılığı. 105 GB’lık bir IoStore oyunu, saatler değil saniyeler içinde birkaç kilobaytlık .locres’e iner. retoc kapsayıcının kendi AES’ini ve Oodle’ını da işler; IoStore oyunlarının, gevşek pak’ların takılabildiği Oodle sorununu es geçmesinin nedeni budur.
Bunun önemli yarısı şu: IoStore yalnızca okumayı karmaşıklaştırır. Yazma evrenseldir ve sıradaki bölüm de odur.
Çıktı, yeniden inşa edilmiş bir oyun değil, bir geçersiz kılma pak’ıdır
Rakip kılavuzların hiçbirinin düzgün açıklamadığı kısım budur — ve Unreal çevirisinin bir kez çalıştığında ucuz olmasının nedeni de budur.
Unreal, pak dosyalarını tanımlı bir sırayla takar ve adı `_P` ile biten her arşiv en son takılır. Sonraki takmalar kazanır. Dolayısıyla, temel oyunun kullandığı sanal yolun aynısında, yalnızca sizin değiştirilmiş .locres’inizi içeren küçük bir arşiv orijinali basitçe gölgeler — yerelleştirme yöneticisi sizinkini yükler ve gönderilen dosyayı hiç görmez.
- Yeniden imzalama yok. Pak imzalama tamamen ayrı bir RSA mekanizmasıdır ve gönderilen tüketici oyunlarında nadiren zorunlu tutulur; geçersiz kılma ona hiç dokunmaz.
- Çıktı için AES anahtarı gerekmez. Geçersiz kılma, şifresiz ve sıkıştırmasız yazılır. Anahtar yalnızca orijinali okumak için gerekliydi.
- Oyunun yeniden paketlenmesi yok. Temel arşivler dokunulmadan kalır. 60 GB’lık bir kurulum 60 GB kalır; çeviriniz kilobaytlarla ölçülen bir dosyadır.
- IoStore oyunlarında da çalışır.
.locres, Zen paket yükleyicisi yerine pak dosya sistemi üzerinden okunur, dolayısıyla varlıklarının tamamı.utoc/.ucasiçinde yaşayan bir UE5 oyunu bile gevşek, düz bir_P.pak’ı alır.
Kurulumu, üretilen _P.pak dosyasını <Game>/Content/Paks/ içine — orijinallerin durduğu klasöre — kopyalayarak yaparsınız. Bazı oyunlar ayrıca bir ~mods/ alt klasörü takar, ki o da aynı şekilde çalışır. Çeviriyi kaldırmak o tek dosyayı silmek demektir; bu da geri dönmeyi önemsiz kılar ve erken denemeyi güvenli hâle getirir.
Adımlar
- RuneTranslate’i indirme sayfasından kurun ve giriş yapın. İlk açılışta ücretsiz bir Patreon girişi gerekir; ücretsiz katman her motoru ve her sağlayıcıyı açar — verimi kısıtlar ve aynı anda tek proje tutar.
- Yeni bir proje oluşturun ve oyunun kök klasörüne yönlendirin — yürütülebilir dosyayı ve
<Game>dizinini içeren klasör. AlgılamaContent/Paks’a ve pak alt bilgi imzasına ya da.utoc/.ucas’a bakar. - Arşivler şifreliyse anahtar kurtarmanın çalışmasına izin verin. Gönderilen ikilileri tarar ve her adayı pak’ın kendi dizin hash’ine karşı doğrular. Eli boş dönerse, iletişim kutusuna bir anahtar yapıştırın.
- Çıkarmanın bitmesini bekleyin. Kaynak kültürün
.locresgirişlerini, yerelleştirme hedefine göre gruplanmış ve incelemeye hazır hâlde alırsınız. - Bir sağlayıcı seçip çevirin. İsterseniz kısa arayüz dizeleri ile uzun diyalog farklı sağlayıcılara yönlendirilebilir, böylece parayı yalnızca gerektiği yerde harcarsınız.
- Geleni inceleyin. Makine çevirisinin en zayıf olduğu yer menü dizeleridir — çıplak bir
Saveya daLoadhiçbir bağlam taşımaz ve cümle olarak geri dönen iki kelimelik bir düğme kendi bileşeninden taşar. - Dışa aktarın. RuneTranslate, değiştirilmiş
.locres’inizi doğru motor-göreli yolda tutan tek bir şifresiz_P.pakyazar. - O dosyayı
<Game>/Content/Paks/içine kopyalayın ve oyunu başlatın.
Tüm oyunu bir sağlayıcıdan geçirmeden önce, bir avuç dize çevrilmiş hâldeyken 8. adımdan sonra test edin. Geçersiz kılma yok sayılacaksa — yanlış klasör, yanlış kültür, alışılmadık bir takma düzeni — bunu 9.000 dizenin parasını ödedikten sonra değil, beş dakika içinde öğrenmek istersiniz.
Yer tutucular ve zengin metin
Unreal’ın FText biçimlendirmesi konumsal argümanlar için {0}, {1}, adlandırılmış olanlar için {PlayerName}, {Count} kullanır; buna satır içi biçimlendirme için </> kapatıcılı <RichText> işaretlemesi de eklenir. Bir çeviri sağlayıcısı bunlardan birini düşürür ya da bozarsa, oyun size biraz yanlış bir cümle göstermez — bozuk bir biçim dizesi gösterir ya da argüman satırdan sessizce kaybolur.
RuneTranslate bunların her birini, sağlayıcı dizeyi görmeden önce nötr bir yer tutucuya maskeler ve sonrasında geri yükler. Sağlayıcı işaretlerin içinden değil, etraflarından çevirir; dolayısıyla bir argüman, süslü ayraçları yazım hatası sanan bir model tarafından silinemez. Daha ileri gidip belirli dizeleri çeviriden tamamen uzak tutmak isterseniz, regex hariç tutma filtreleri her motorda çalışır ve bir sözlük özel adları oyun boyunca sabit tutar.
Aksan tuzağı: bu bir font sorunu değil, kodlama hatasıdır
Bunu ayrıca belgelemeye değer, çünkü belirti tam olarak yanlış yönü işaret ediyor. Unreal bir dizeyi uzunluk önekiyle serileştirir: pozitif uzunluk karakter başına bir bayt, negatif uzunluk UTF-16 demektir. Motor dar biçimi yalnızca her karakter 7 bitlik ASCII olduğunda seçer — denetimi 0x7F’in üstündeki her şeyi reddeder. Yükleyicisi de aynı şekilde kurulmuştur, dolayısıyla eline yüksek bayt içeren dar bir dize geçerse, her birinin yerine düz bir ? koyar.
Pratik sonucu şu: dar biçimde yazılmış poción mágica içeren bir çeviri oyuncuya poci?n m?gica olarak ulaşır. Etkilenen bant U+0080–U+00FF’dir, ki bu tam olarak İspanyolca, Fransızca, Almanca, Portekizce, İtalyanca ve İskandinav dillerinin aksanlı harfleridir. Lehçe, Türkçe, Çekçe, Yunanca, Kiril, Japonca ve Çince ise U+00FF’in üstünde oturur, otomatik olarak geniş dalı alır ve hiç etkilenmez.
Yani parmak izi şudur: aksanlar İspanyolcada bozulur ama Rusça gayet iyidir. Bunu görüyorsanız, sorun oyunun fontundaki eksik bir glif değil, dosyayı yazan şeydeki bir kodlama hatasıdır — eksik bir glif kutu olarak ya da hiç görünmeyerek işlenir, asla soru işareti olarak değil. RuneTranslate’te tam olarak bu hata vardı ve 0.49.4’te düzeltildi; kodlayıcı artık tek bir yerde yaşıyor ve ASCII dışındaki her şey için geniş biçimi yazıyor. Bunu bilmekte fayda var, çünkü bu alandaki başka araçlar hâlâ yanlış yapıyor.
Sağlayıcı seçimi
Dokuz sağlayıcının üçü hiçbir API anahtarı gerektirmez — Google, ücretsiz DeepL ve DeepL’in Classic/Next-gen modelleri — ve ücretsiz katman hepsini verir. Çoğunlukla arayüzden ibaret bir oyun için ücretsiz bir sağlayıcı gerçekten yeterlidir. Diyalog ağırlıklı oyunlarda bir LLM sağlayıcısı bağlamı çok daha iyi taşır; OpenAI, Anthropic, DeepSeek, herhangi bir OpenAI uyumlu uç nokta ve Ollama ya da LM Studio üzerinden yerel bir model mevcuttur. Sağlayıcı karşılaştırması her birinin neyde iyi, neyde kötü olduğunu gerçek maliyet rakamlarıyla anlatır.
Sorun giderme
Oyun çalışıyor ama hiçbir şey çevrilmemiş
Neredeyse her zaman üç şeyden biri. Dosya <Game>/Content/Paks/ içinde değildir — yürütülebilir dosyanın yanına koymak hiçbir işe yaramaz. Dosya adı _P sonekini kaybetmiştir; bu durumda sıradan alfabetik sırada takılır ve temel pak kazanabilir. Ya da oyun, çevirmediğiniz bir kültürde çalışıyordur: açılışta hangi kültürü çözdüyse onun .locres’ini yükler, dolayısıyla en’i zorlayan bir oyun yalnızca ja için yazılmış bir geçersiz kılmayı yok sayar. Önce oyunun dil ayarını kontrol edin.
Oodle ile sıkıştırılmış gevşek bir pak’ta çıkarma başarısız oluyor
Oodle ile sıkıştırılmış gevşek bir .pak, paketlenemeyen bir açıcıya ihtiyaç duyar. Oyun ayrıca IoStore kapsayıcıları da gönderiyorsa, retoc yolu Oodle’ı işler ve sorun kalmaz. Yalnızca gevşek pak varsa, bu şimdilik kesin bir duraktır ve sessiz bir boş sonuç yerine açıkça bildirilir.
Oyunda hiçbir yerde .locres yok
O hâlde metni pişirilmiş varlıklara derlenmiştir ve bu yol ona ulaşmaz. En net örnek, IoStore dizini hiç dosya adı olmadan içerik hash’lerine indirgenmiş büyük, canlı hizmet veren bir UE5 oyunudur — yüz binlerce parça ve sıfır .locres. RuneTranslate, kapsayıcının tamamını öğütmek yerine bunu söyler.
Algılama hiç çalışmıyor
Content/Paks’ın kendisine ya da başka oyunlarla dolu bir üst klasöre değil, yürütülebilir dosyayı içeren klasöre yönlendirin. Yine de algılamıyorsa, paketleme alışılmadıktır ve bildirmeye değer — pak formatının sürüme özgü alt bilgi düzenleri vardır ve kimsenin görmediği bir lehçe, tam olarak eklenebilecek türden bir şeydir.
Dürüst sınırlar
Unreal desteği en iyi çabadır. Gevşek ve şifreli pak’ların ve UE5 IoStore’un içindeki .locres kanıtlanmış yoldur; bir UE4 oyununda İspanyolca olarak oyun içinde oynanabilir olduğu doğrulandı. DataTable ve pişirilmiş .uasset metni kapsanmaz. IoStore karşılığı olmayan, Oodle ile sıkıştırılmış gevşek pak’lar desteklenmez. İmzalaması zorunlu tutulan pak’lar geçersiz kılınamaz, ama bunlar pratikte nadirdir. Ve format, motor sürümleri ile stüdyolar arasında bu kadar değiştiği için, ilk dışa aktarımı teslim edilecek iş değil, bir test olarak görün.
Elinizde kalan şey, kendi bilgisayarınızda tuttuğunuz oynanabilir, çevrilmiş bir sürümdür: orijinal oyun dokunulmadan durur, yanında da her şeyi geri almak için silebileceğiniz küçük bir dosya. Motorları karşılaştırıyorsanız ya da oyununuzun kapsanıp kapsanmadığına bakıyorsanız, Unreal motor sayfası teknik ayrıntıyı içerir ve tüm motorlar, Unity ile RPG Maker dahil desteklenen on yedi formatı listeler. Sürecin tamamına yeniyseniz, genel nasıl yapılır ile başlayın ve Unreal’a özgü kısımlar için buraya dönün.
RuneTranslate'i denemeye hazır mısın?
Ücretsiz katman her motoru + her çeviri sağlayıcısını açar. Supporter ($3/mo) tam hızı açar.
Windows için indir
