كيفية ترجمة ألعاب Unreal Engine
تشحن ألعاب Unreal نصّها في جداول .locres مُصرَّفة داخل حاويات .pak أو IoStore. إليك كيف تُقرأ، ولماذا يكون الإخراج حزمة تجاوز صغيرة لا لعبة معاد بناؤها.
تبدو لعبة Unreal Engine أصعب شيء على قرصك للترجمة. لا مجلد data، ولا ملفات سكربت، ولا .json تفتحه — مجرّد ملف تنفيذي، ودليل Content/Paks يحوي ملف .pak ضخماً أو اثنين، وربما زوج حاويات .utoc/.ucas. والخبر الجيد أن النص الذي تريده فعلاً ليس مخفياً داخل تلك الملفات بحكم التصميم عادةً. فلدى Unreal نظام توطين من الطراز الأول، ومعظم الألعاب المشحونة تستخدمه. ومهمّتك أن تجد الجدول، وتستبدل السلاسل، وتسلّم المحرك ملفاً صغيراً له أولوية على الأصل.
ذلك الجزء الأخير هو ما يجعل Unreal لطيفاً بمجرّد أن تفهمه. أنت لا تعيد بناء لعبة بحجم 60 غيغابايت. بل تنتج أرشيف تجاوز يُقاس بالكيلوبايتات وتُسقطه بجانب الأصول.
شيء واحد قبل الخطوات: دعم Unreal في RuneTranslate أفضل جهد ممكن وأحدث من محرّكات مثل RPG Maker أو Ren’Py. وقد تأكّد تشغيله على عناوين UE4 حقيقية، لكن سطح الصيغة هائل وكل استوديو يحزم بطريقته. تحقّق من نسخة مصدَّرة داخل اللعبة قبل الالتزام بتشغيل ترجمة طويل.
ما الذي تشحنه لعبة Unreal فعلاً
يُبقي Unreal النص الموجَّه للاعب في ملفات `.locres` — الصورة المُصرَّفة من FTextLocalizationResource. واحد لكل ثقافة، مرتّب على مسار مثل <Game>/Content/Localization/Game/ja/Game.locres، مع أشقّاء لـ en وzh-Hans وما شحنه الاستوديو غير ذلك. وحتى لعبة بلا أي ترجمات تملك واحداً عادةً، للثقافة التي أُلّفت بها.
ملف .locres ليس ملفاً نصياً ولا قائمة مفتاح/قيمة بسيطة. بل جدول ثنائي منظّم كـمساحات أسماء، تحمل كل منها مفاتيح، ويشير كل مفتاح إلى سلسلة. وفي الإصدارات الحديثة تُخزَّن مساحة الاسم والمفتاح كـتجزئات (CRC32 في الإصدار 2، وCityHash64 على UTF-16 في الإصدار 3) بدل أسماء مقروءة، وتعيش السلاسل نفسها في جدول بحث مشترك منزوع التكرار مع عدّادات مرجعية. ولا تبحث بيئة التشغيل عن سلسلة بنصّها الإنجليزي أبداً — بل تبحث عنها بزوج مساحة الاسم/المفتاح، المُصرَّف في Blueprints اللعبة وشيفرة C++ وقت البناء.
تلك البنية تملي الطريقة الآمنة الوحيدة لتحرير واحد منها. يحفظ RuneTranslate كل تجزئة مساحة اسم وتجزئة مفتاح وتجزئة سلسلة مصدر بايتاً ببايت ولا يغيّر سوى القيمة، ثم يعيد بناء جدول السلاسل منزوع التكرار وعدّاداته المرجعية. لا شيء يعيد حساب تجزئة، فلا شيء يستطيع إنتاج مفتاح تعجز اللعبة عن إيجاده. والترجمات حرّة في أن تكون أطول أو أقصر من الأصل.
ثم تُحزَم ملفات .locres هذه في أرشيفات .pak — تُعرَّف بقيمة سحرية 0x5A6F12E1 في تذييل عند نهاية الملف تماماً — أو، في عناوين UE5 الحديثة، في حاويات IoStore بصيغة .utoc/.ucas.
تحقّق من النطاق قبل أن تنفق ساعة
يغطّي .locres الواجهة والقوائم ورسائل النظام ونصوص التعليم وأسماء العناصر والمهارات والترجمات المصاحبة — سمّها نحو 90% من النص المرئي في لعبة نموذجية. وهذا هو الجزء الذي يقرؤه RuneTranslate ويكتبه.
وما لا يغطّيه: النص المُصرَّف في DataTables أو المخبوز في حزم `.uasset` المطبوخة. بعض الاستوديوهات — خصوصاً في المشاريع الأصغر أو المدفوعة بـ Blueprint بكثافة — تُبقي حوارها هناك بدل نظام التوطين. وتلك السلاسل معنونة بالتجزئة داخل حزم مطبوخة بلا فهرس أدلّة مقروء، وقراءتها كما ينبغي تحتاج ملف تخطيط .usmap لا تتضمّنه اللعبة المشحونة. فإن كانت لعبتك تُبقي سكربتها هناك، سيعود الاستخراج بالقوائم والأزرار ولا شيء من الحوار، ويبلّغ RuneTranslate بذلك كنتيجة صريحة خارج النطاق بدل التظاهر بالنجاح.
ويستحقّ أن تعرف مبكراً: أسرع طريقة للتحقّق أن تشغّل خطوة إنشاء المشروع وتنظر إلى ما خرج. بضع مئات من السلاسل القصيرة تبدو كلها مثل Continue وOptions وAre you sure? تعني أن الواجهة مترجَمة والسكربت لا. وعدة آلاف من السلاسل تتضمّن جملاً كاملة تعني أنك في وضع جيد.
مفتاح AES، ولماذا ليس جداراً
شريحة كبيرة من الحزم المشحونة مشفّرة بـ AES-256 — تحديداً بنمط ECB دون متجّه تهيئة، مطبَّقاً على فهرس الأرشيف وغالباً على المدخلات المفردة. ودون المفتاح يكون الأرشيف معتماً: لا تستطيع حتى سرد ما بداخله.
والمفتاح قابل للاستعادة لسبب مباشر. على اللعبة أن تقرأ أرشيفاتها بنفسها أثناء التشغيل، على جهاز بلا شبكة ولا خادم تراخيص، فالمفتاح موجود في الملف الثنائي المشحون كبيانات عادية. يفحص RuneTranslate الملف التنفيذي وملفات DLL الخاصة به بحثاً عن نوافذ من 32 بايت، ويقلّمها ببوابة عشوائية (مفتاح AES حقيقي يحوي 25 بايتاً مميزاً على الأقل من أصل 32)، ويجري فحص سلامة رخيصاً بفكّ تشفير أول كتلة من الفهرس وسؤال ما إذا كانت القيمة الأولى تُقرأ كطول سلسلة معقول، ثم يتحقّق من الناجين كما ينبغي: يفكّ تشفير الفهرس كاملاً ويقارن SHA-1 الخاص به بالتجزئة التي يسجّلها تذييل الحزمة نفسه. وتلك الخطوة الأخيرة هي الفرق بين هذا وبين باحثي المفاتيح المرتّبين بالعشوائية المنتشرين — فالمرشّح إمّا يعيد إنتاج التجزئة المسجّلة في الأرشيف نفسه أو يُرفض. ولا يمكن قبول مفتاح خاطئ أبداً.
وبعض الألعاب تخزّن المفتاح كنصّ بدل بايتات خام، وبعضها يوزّعه على تعليمات منفصلة في الملف الثنائي؛ والحالتان معالَجتان. وإن لم ينجح شيء من ذلك، يقبل حوار New Project مفتاحاً ملصوقاً بصيغة hex (0x… أو 64 محرفاً ست عشرياً) أو base64، ويُخزَّن المفتاح بعد استعادته لكل مشروع كي لا تعيد فحص ملف تنفيذي بحجم 85 ميغابايت عند كل تصدير.
IoStore في UE5 مختلف، والاستخراج مُوجَّه
تشحن عناوين UE5 على نحو متزايد حاويات IoStore بدل حزم pak عادية: دليل .utoc مقترناً بكتلة بيانات .ucas، بضغط Oodle وتشفيرها الخاص. والنهج الساذج هنا فكّ كل شيء، وعلى لعبة بحجم 105 غيغابايت ليس ذلك نهجاً أصلاً.
يضمّن RuneTranslate أداة retoc (مرخّصة MIT) ويطلب منها تحويل الحاويات إلى pak قديم الطراز مُرشَّحاً على ملفات التوطين وحدها — ما يكافئ to-legacy -f locres --no-shaders --no-script-objects. فيتقلّص عنوان IoStore بحجم 105 غيغابايت إلى بضعة كيلوبايتات من .locres، في ثوانٍ لا ساعات. وretoc يتولّى كذلك AES الخاص بالحاوية وOodle، ولهذا تتفادى ألعاب IoStore مشكلة Oodle التي قد تصطدم بها الحزم الحرة.
والنصف المهمّ في هذا أن IoStore يعقّد القراءة فقط. أما الكتابة فعامّة، وهي القسم التالي.
الإخراج حزمة تجاوز، لا لعبة معاد بناؤها
هذا هو الجزء الذي لا يشرحه أي دليل منافس كما ينبغي، وهو سبب رخص ترجمة Unreal بمجرّد أن تعمل أصلاً.
يركّب Unreal ملفات pak بترتيب محدّد، وأي أرشيف ينتهي اسمه بـ`_P` يُركَّب أخيراً. والتركيب المتأخّر يفوز. فأرشيف صغير لا يحوي سوى ملف .locres المعدَّل لديك، على المسار الافتراضي نفسه الذي تستخدمه اللعبة الأساسية، يظلّل الأصل ببساطة — يحمّل مدير التوطين نسختك ولا يرى المشحونة أبداً.
- لا إعادة توقيع. توقيع الحزم آلية RSA منفصلة تماماً ونادراً ما تُفرَض في العناوين الاستهلاكية المشحونة؛ والتجاوز لا يمسّها.
- لا حاجة إلى مفتاح AES للإخراج. تُكتب حزمة التجاوز غير مشفّرة وغير مضغوطة. ولم يكن المفتاح لازماً إلا لـقراءة الأصل.
- لا إعادة تحزيم للعبة. الأرشيفات الأساسية دون مساس. تثبيت بحجم 60 غيغابايت يبقى 60 غيغابايت؛ وترجمتك ملف يُقاس بالكيلوبايتات.
- وهي تعمل لألعاب IoStore أيضاً. يُقرأ
.locresعبر نظام ملفات pak لا عبر محمّل حزم Zen، فيُلتقط ملف_P.pakحرّ عادي حتى في لعبة UE5 تعيش كل أصولها في.utoc/.ucas.
تثبّتها بنسخ ملف _P.pak الناتج إلى <Game>/Content/Paks/ — المجلد نفسه الذي تقبع فيه الأصول. وبعض الألعاب تركّب أيضاً مجلداً فرعياً باسم ~mods/، وهو يعمل بالقدر نفسه. وإزالة الترجمة حذف ذلك الملف الواحد، ما يجعل التراجع تافهاً ويجعل الاختبار المبكر آمناً.
الخطوات
- ثبّت RuneTranslate من صفحة التنزيل وسجّل الدخول. يلزم تسجيل دخول مجاني عبر Patreon عند أول إطلاق؛ وتفتح الفئة المجانية كل محرك وكل مزوّد — فهي تقيّد السرعة وتُبقي مشروعاً واحداً في المرة.
- أنشئ مشروعاً جديداً ووجّهه إلى مجلد اللعبة الجذر — الذي يحوي الملف التنفيذي ودليل
<Game>. يبحث الاكتشاف عنContent/Paksوعن القيمة السحرية في تذييل الحزمة، أو عن.utoc/.ucas. - إن كانت الأرشيفات مشفّرة، فدع استعادة المفتاح تعمل. تفحص الملفات الثنائية المشحونة وتتحقّق من كل مرشّح مقابل تجزئة فهرس الحزمة نفسها. وإن عادت فارغة، فالصق مفتاحاً في الحوار.
- دع الاستخراج ينتهي. تحصل على مدخلات
.locresلثقافة المصدر، مصنّفةً حسب هدف التوطين، جاهزةً للمراجعة. - اختر مزوّداً وترجم. يمكن توجيه سلاسل الواجهة القصيرة والحوار الطويل إلى مزوّدين مختلفين إن أردت أن تنفق المال حيث يهمّ فقط.
- راجع ما عاد. سلاسل القوائم هي حيث تكون الترجمة الآلية أضعف — فـ
SaveأوLoadمجرّدة بلا سياق، وزرّ من كلمتين يعود جملةً سيفيض عن عنصر واجهته. - صدّر. يكتب RuneTranslate ملف
_P.pakواحداً غير مشفّر يحوي.locresالمعدَّل لديك على المسار الصحيح نسبةً إلى المحرك. - انسخ ذلك الملف إلى
<Game>/Content/Paks/وأطلق اللعبة.
اختبر بعد الخطوة 8 بحفنة سلاسل مترجمة قبل أن تمرّر اللعبة كاملة على مزوّد. فإن كان التجاوز سيُتجاهَل — مجلد خاطئ، أو ثقافة خاطئة، أو إعداد تركيب غير معتاد — فأنت تريد أن تعرف خلال خمس دقائق، لا بعد أن تدفع مقابل 9,000 سلسلة.
العناصر النائبة والنص المنسّق
يستخدم تنسيق FText في Unreal الرمزين {0} و{1} للوسائط الموضعية و{PlayerName} و{Count} للمسمّاة، إضافةً إلى ترميز <RichText> مع مغلقات </> للتنسيق داخل السطر. فإن أسقط مزوّد ترجمة واحداً منها أو أفسده، لا تعرض اللعبة جملة خاطئة قليلاً — بل تعرض سلسلة تنسيق مكسورة، أو يختفي الوسيط من السطر بصمت.
يخفي RuneTranslate كل واحد منها خلف عنصر نائب محايد قبل أن يرى المزوّد السلسلة، ثم يستعيدها بعدها. يترجم المزوّد حول العلامات لا عبرها، فلا يمكن لنموذج قرّر أن الأقواس المعقوفة تبدو خطأً مطبعياً أن يحذف وسيطاً. وإن أردت أن تمضي أبعد وتحجب سلاسل بعينها عن الترجمة كلياً، تعمل مرشّحات الاستبعاد النمطية على أي محرك، ويُبقي المسرد أسماء الأعلام ثابتة عبر اللعبة كلها.
مصيدة الحروف المشكولة، وهي خطأ ترميز لا خطأ في الخط
تستحقّ هذه توثيقاً مستقلاً لأن العرَض يشير في الاتجاه الخاطئ تماماً. يُسلسل Unreal السلسلة بسابقة طول: الطول الموجب يعني بايتاً واحداً لكل محرف، والسالب يعني UTF-16. ولا يختار المحرك الصورة الضيّقة إلا حين يكون كل محرف من ASCII بسبع بتّات — ففحصه يرفض أي شيء فوق 0x7F. ومحمّله مبنيّ بالطريقة نفسها، فإن سُلّم سلسلة ضيّقة تحوي بايتاً عالياً، أحلّ محلّ كل واحد منها علامة استفهام ? حرفية.
والنتيجة العملية: ترجمة تحوي poción mágica مكتوبةً بالصورة الضيّقة تصل اللاعب كـpoci?n m?gica. والنطاق المتأثّر هو U+0080–U+00FF، وهو بالضبط الحروف المشكولة في الإسبانية والفرنسية والألمانية والبرتغالية والإيطالية ولغات الشمال. أما البولندية والتركية والتشيكية واليونانية والسيريلية واليابانية والصينية فتقع كلها فوق U+00FF، وتأخذ الفرع العريض تلقائياً، ولا تتأثّر أبداً.
فالبصمة إذن: تنكسر الحروف المشكولة في الإسبانية بينما الروسية سليمة. إن رأيت ذلك، فهو خطأ ترميز في أي شيء كتب الملف، لا محرف ناقص في خط اللعبة — فالمحرف الناقص يُرسَم مربّعاً أو لا شيء، لا علامة استفهام أبداً. وقد وقع RuneTranslate في هذا الخطأ بالضبط وأصلحه في 0.49.4؛ ويعيش المُرمِّز الآن في مكان واحد ويكتب الصورة العريضة لأي شيء خارج ASCII. ويستحقّ أن تعرفه لأن أدوات أخرى في هذا المجال ما زالت تخطئ فيه.
اختيار مزوّد
ثلاثة من المزوّدين التسعة لا يحتاجون مفتاح API أصلاً — Google، وDeepL المجانية، ونماذج DeepL بخيار Classic/Next-gen — وتمنحك الفئة المجانية هؤلاء كلهم. وللعبة أغلبها واجهة، المزوّد المجاني جيد فعلاً. أما العناوين كثيفة الحوار، فيتعامل مزوّد نموذج لغوي مع السياق أفضل بكثير؛ وOpenAI وAnthropic وDeepSeek وأي واجهة متوافقة مع OpenAI ونموذج محلي عبر Ollama أو LM Studio كلها متاحة. تمشي مقارنة المزوّدين عبر ما يجيده كل واحد وما يخفق فيه، بأرقام تكلفة حقيقية.
حلّ المشكلات
اللعبة تعمل لكن لا شيء مترجم
في الغالب أحد ثلاثة. الملف ليس في <Game>/Content/Paks/ — ووضعه بجانب الملف التنفيذي لا يفعل شيئاً. أو فقد اسم الملف لاحقة _P، وعندها يُركَّب بترتيب أبجدي عادي وقد تفوز الحزمة الأساسية. أو اللعبة تعمل بثقافة لم تترجمها: فهي تحمّل .locres للثقافة التي حلّتها عند الإقلاع، ولعبة تفرض en ستتجاهل تجاوزاً مكتوباً لـja فقط. تفقّد إعداد لغة اللعبة أولاً.
الاستخراج يفشل على حزمة pak حرة مضغوطة بـ Oodle
تحتاج حزمة .pak حرة مضغوطة بـ Oodle فاكّ ضغط لا يمكن تضمينه. فإن كانت اللعبة تشحن حاويات IoStore أيضاً، يتولّى مسار retoc أمر Oodle وأنت بخير. أما إن كانت حزماً حرة فقط، فهذا توقّف تامّ حالياً، مُبلَّغ عنه صراحةً لا كنتيجة فارغة صامتة.
اللعبة لا تحوي أي .locres
إذن نصّها مُصرَّف في أصول مطبوخة، وهذا المسار لا يصل إليه. وأوضح مثال عنوان UE5 كبير من نوع الخدمة الحية جُرّد فهرس IoStore فيه إلى تجزئات محتوى بلا أي أسماء ملفات — مئات آلاف القطع وصفر .locres. يقول RuneTranslate ذلك بدل أن يطحن الحاوية كاملة.
الاكتشاف لا يعمل أصلاً
وجّهه إلى المجلد الذي يحوي الملف التنفيذي، لا إلى Content/Paks نفسه ولا إلى مجلد أب مليء بألعاب أخرى. وإن ظلّ لا يكتشف، فالتحزيم غير معتاد ويستحقّ الإبلاغ — فلصيغة pak تخطيطات تذييل خاصة بكل إصدار، ولهجة لم يرها أحد بعد هي بالضبط نوع الشيء الذي يُضاف.
حدود صادقة
دعم Unreal أفضل جهد ممكن. ملفات .locres داخل الحزم الحرة والمشفّرة وداخل IoStore في UE5 هي المسار المثبت، مؤكَّد التشغيل داخل اللعبة على عنوان UE4 بالإسبانية. أما نصوص DataTable و.uasset المطبوخة فغير مغطّاة. والحزم الحرة المضغوطة بـ Oodle دون نظير IoStore غير مدعومة. والحزم التي تُفرض عليها التواقيع لا يمكن تجاوزها، وإن كانت نادرة عملياً. ولأن الصيغة تتباين كثيراً بين إصدارات المحرك والاستوديوهات، عامل التصدير الأول كاختبار لا كمنتج نهائي.
وما ينتهي بين يديك نسخة مترجمة قابلة للعب تحتفظ بها على جهازك: اللعبة الأصلية دون مساس، إضافةً إلى ملف صغير واحد تحذفه فتتراجع عن كل شيء. وإن كنت تقارن المحرّكات أو تتحقّق مما إذا كانت لعبتك مغطّاة أصلاً، تحمل صفحة محرك Unreal التفاصيل التقنية ويسرد كل المحرّكات الصيغ السبع عشرة المدعومة، ومنها Unity وRPG Maker. وإن كنت جديداً على العملية كلها، فابدأ بـالدليل العام وعُد إلى هنا لأجزاء Unreal الخاصة.
مستعد لتجربة RuneTranslate؟
تفتح الباقة المجانية كل محرك + كل مزود ترجمة. باقة Supporter ($3/mo) تفتح السرعة الكاملة.
التنزيل لنظام Windows
