R8 की मदद से, Unreal Engine कोड को छोटा और ऑप्टिमाइज़ करना

Unreal Engine में आपके गेम का मुख्य लॉजिक C++ या ब्लूप्रिंट में लिखा जाता है. हालांकि, Android पैकेजिंग, Java और Kotlin बाइट कोड (classes.dex) को कंपाइल करती है, ताकि GameActivity लाइफ़साइकल इवेंट, Google Play services, बिलिंग, ऑडियो, और आंकड़ों के प्लगिन को मैनेज किया जा सके.

R8, Android Gradle प्लगिन (AGP) में डिफ़ॉल्ट रूप से मौजूद कोड श्रिंकर और ऑप्टिमाइज़र है. यह इस्तेमाल न की गई क्लास और तरीकों को हटाता है और बाइट कोड को ऑप्टिमाइज़ करता है. इससे न सिर्फ़ आपके पैकेज का डाउनलोड साइज़ कम होता है, बल्कि मेमोरी-मैप किए गए (mmap) DEX पेजों और बेसलाइन Java प्रोसेस ओवरहेड के रनटाइम मेमोरी फ़ुटप्रिंट भी कम होते हैं. इससे, फ़िज़िकल मेमोरी पर दबाव कम होता है और लो मेमोरी किलर (एलएमके) की वजह से ऐप्लिकेशन बंद होने की समस्या कम होती है. Google Play, Android की ज़रूरी जानकारी में मौजूद DEX कोड ऑप्टिमाइज़ेशन मेट्रिक की मदद से, आपके गेम के DEX ऑप्टिमाइज़ेशन लेवल पर भी नज़र रखता है.

डिफ़ॉल्ट ऐक्शन और सेटिंग और Unreal Engine के साथ काम करने वाले वर्शन

UE 4.22.0 से, Unreal Engine का UEDeployAndroid.cs, जनरेट किए गए Android रिलीज़ के लिए तैयार बिल्ड कॉन्फ़िगरेशन (buildAdditions.gradle) में डिफ़ॉल्ट रूप से minifyEnabled true इंजेक्ट करता है. UE 4.25 ने बंडल किए गए टूल चेन को AGP 4.0.0 पर अपग्रेड किया है. इसलिए, UE 4.25 और इसके बाद के वर्शन में, सभी रिलीज़ (शिपिंग और डिस्ट्रिब्यूशन) बिल्ड पर R8 डिफ़ॉल्ट रूप से चालू (true) रहता है. इसके लिए, किसी अतिरिक्त सेटअप की ज़रूरत नहीं होती.

Unreal Engine का वर्शन बंडल किया गया एजीपी रिलीज़ का डिफ़ॉल्ट तरीका डीबग डिफ़ॉल्ट व्यवहार
UE 4.21 और इससे पहले के वर्शन लेगसी Gradle या Ant बंद है (false) बंद है (false) इंजन ने कोई minifyEnabled कॉन्फ़िगरेशन इंजेक्ट नहीं किया है.
UE 4.22 से 4.24 3.4 से पहले के वर्शन चालू है (ProGuard) बंद है (false) रिलीज़ के लिए तैयार बिल्ड में, minifyEnabled true डिफ़ॉल्ट रूप से चालू रहता है (ProGuard को चलाता है).
UE 4.25 से 5.3 4.0.0 चालू है (R8) बंद है (false) AGP 4.0 को अपनाने पर, रिलीज़ के लिए तैयार बिल्ड में R8 डिफ़ॉल्ट रूप से चलता है.
UE 5.4 से 5.7 7.4.2 चालू है (R8) बंद है (false) AGP 7.x, लेगसी useProguard विकल्पों को हटा देता है; R8 खास तौर पर चलता है.
UE 5.8 (5.8.3+) 8.13.0 चालू है (R8) बंद है (false) यह डिफ़ॉल्ट रूप से, AGP 8.x और आधुनिक R8 ऑप्टिमाइज़ेशन पाइपलाइन का इस्तेमाल करता है.

रिलीज़ और डीबग के लिए बिल्ड के बीच अंतर

UnrealBuildTool (UEDeployAndroid.cs), जनरेट की गई buildAdditions.gradle फ़ाइल को रिलीज़ और डीबग बिल्ड के लिए अलग-अलग तरीके से कॉन्फ़िगर करता है:

buildTypes {
    release {
        signingConfig signingConfigs.release
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        debuggable true
        signingConfig signingConfigs.debug
    }
}
  • रिलीज़ (शिपिंग या डिस्ट्रिब्यूशन): यह minifyEnabled true को सेट करता है और डिफ़ॉल्ट रूप से proguard-rules.pro को लागू करता है. साथ ही, R8 कोड को छोटा करने और कोड को छिपाने की सुविधा को चालू करता है.
  • डीबग (डेवलपमेंट): यह debuggable true को चालू करता है और minifyEnabled को हटा देता है (डिफ़ॉल्ट रूप से false पर सेट होता है), ताकि बिल्ड को तेज़ी से दोहराया जा सके और सिंबल को डीबग किया जा सके.

Unreal Plugin Language (UPL) का इस्तेमाल करके, Keep के नियम जोड़ना

UE 4.25 और इसके बाद के वर्शन में, रिलीज़ के लिए तैयार बिल्ड पर R8 अपने-आप चलता है. इसलिए, आपको उन Java क्लास को सुरक्षित रखना होगा जिन्हें सिर्फ़ C++ JNI (JNIEnv->FindClass, GetMethodID) या मेनिफ़ेस्ट के ज़रिए ऐक्सेस किया जा सकता है. जिन क्लास में Java कॉल साइट नहीं होती हैं उन्हें इस्तेमाल न की गई क्लास माना जाता है और R8 उन्हें हटा देता है. इसकी वजह से, डेवलपमेंट बिल्ड में काम करने वाली सुविधाएं, शिपिंग बिल्ड में ClassNotFoundException या NoSuchMethodError के साथ काम नहीं करती हैं.

पैकेजिंग के दौरान, proguard-rules.pro में कस्टम कीप रूल मर्ज करने के लिए, Unreal प्लगिन लैंग्वेज (यूपीएल) एक्सएमएल फ़ाइल में <proguardAdditions> टैग का इस्तेमाल करें. अपने प्रोजेक्ट या प्लगिन की *_UPL.xml फ़ाइल में यह ब्लॉक जोड़ें:

<root xmlns:android="http://schemas.android.com/apk/res/android">
    <proguardAdditions>
        <insert>
            -keep class com.epicgames.unreal.** { *; }
            -keep class com.example.plugin.** { public *; }
            -dontwarn com.example.plugin.**
        </insert>
    </proguardAdditions>
</root>

अक्सर होने वाली समस्याएं हल करना

इस सेक्शन में, Unreal Engine में R8 का इस्तेमाल करते समय, पैकेजिंग और रनटाइम से जुड़ी आम समस्याओं को हल करने का तरीका बताया गया है.

डीबग करने के लिए, R8 को कुछ समय के लिए बंद करना

अगर आपको यह पता लगाना है कि सिर्फ़ रिलीज़ के दौरान होने वाला क्रैश, R8 की वजह से ज़रूरी क्लास को हटाने से हुआ है, तो अपनी UPL फ़ाइल में <gradleProperties> के नीचे DISABLE_MINIFY=1 डालें. मौजूद होने पर, UEDeployAndroid.cs से minifyEnabled false जनरेट होता है:

<gradleProperties>
    <insert>
        DISABLE_MINIFY=1
    </insert>
</gradleProperties>

Missing classes detected while running R8 पैकेजिंग से जुड़ी गड़बड़ियां

UE 5.4 और इसके बाद के वर्शन (AGP 7.4.2+) में, R8 क्लास मौजूद न होने की जांच सख्ती से करता है. अगर पैकेजिंग इस गड़बड़ी की वजह से पूरी नहीं हो पाती है, तो अपनी इंटरमीडिएट बिल्ड डायरेक्ट्री (Intermediate/Android/.../gradle/app/build/outputs/mapping/release/missing_rules.txt में) में मौजूद missing_rules.txt की जांच करें. साथ ही, अपनी UPL फ़ाइल में मौजूद <proguardAdditions> में, लाइब्रेरी की डिपेंडेंसी या ज़रूरी नियम जोड़ें.

तीसरे पक्ष के SDK टूल के साथ R8 फ़ुल मोड की कंपैटिबिलिटी

UE 5.8 और इसके बाद के वर्शन (AGP 8.13.0+) में, R8 फ़ुल मोड डिफ़ॉल्ट रूप से चालू होता है, ताकि ज़्यादा बेहतर तरीके से ऑप्टिमाइज़ेशन किया जा सके. अगर तीसरे पक्ष का कोई लेगसी Android SDK, रिफ़्लेक्शन से जुड़ी समस्याओं की वजह से रनटाइम के दौरान काम नहीं करता है, तो प्लगिन के ProGuard नियमों को अपडेट करें या R8 को कंपैटबिलिटी मोड पर वापस लाएं. इसके लिए, अपनी UPL फ़ाइल में यह प्रॉपर्टी जोड़ें:

<gradleProperties>
    <insert>
        android.enableR8.fullMode=false
    </insert>
</gradleProperties>