इस कैज़ुअल ड्राइविंग गेम में, अनलिमिटेड और प्रोसेस के हिसाब से जनरेट होने वाली जगहों की मदद से, WebGL की क्षमताओं के बारे में जानें.
Slow Roads एक कैजुअल ड्राइविंग गेम है. इसमें, तय नियमों के मुताबिक जनरेट होने वाली अनलिमिटेड सीनरी पर फ़ोकस किया गया है. यह गेम, ब्राउज़र में WebGL ऐप्लिकेशन के तौर पर होस्ट किया जाता है. कई लोगों को ऐसा लग सकता है कि ब्राउज़र के सीमित कॉन्टेक्स्ट में, ऐसा बेहतर अनुभव नहीं मिल सकता. असल में, इस प्रोजेक्ट का मेरा एक लक्ष्य, इस धारणा को बदलना था. इस लेख में, मैं उन तकनीकों के बारे में बताऊंगा जिनका इस्तेमाल करके मैंने परफ़ॉर्मेंस से जुड़ी समस्याओं को हल किया. इन तकनीकों की मदद से, मैंने वेब पर 3D की संभावित क्षमता को हाइलाइट किया है. आम तौर पर, इस क्षमता को अनदेखा किया जाता है.
ब्राउज़र में 3D डेवलपमेंट
'धीमी सड़कें' सुविधा लॉन्च करने के बाद, मुझे सुझाव/राय/शिकायत वाले सेक्शन में एक ही तरह की टिप्पणी बार-बार दिखी: "मुझे नहीं पता था कि ब्राउज़र में ऐसा किया जा सकता है". अगर आपका भी यही मानना है, तो आप अकेले नहीं हैं. 2022 State of JS सर्वे के मुताबिक, करीब 80% डेवलपर ने अब तक WebGL का इस्तेमाल नहीं किया है. मुझे अफ़सोस है कि ब्राउज़र पर गेमिंग की इतनी संभावनाएं होने के बावजूद, उन्हें इस्तेमाल नहीं किया जा रहा. मुझे उम्मीद है कि Slow Roads की मदद से, WebGL को और ज़्यादा लोकप्रिय बनाया जा सकेगा. साथ ही, "बेहतर परफ़ॉर्मेंस वाला JavaScript गेम इंजन" वाक्यांश से डरने वाले डेवलपर की संख्या भी कम हो सकती है.
WebGL, कई लोगों को रहस्यमय और मुश्किल लग सकता है. हालांकि, हाल के सालों में इसके डेवलपमेंट नेटवर्क, बेहतरीन और सुविधाजनक टूल और लाइब्रेरी में काफ़ी आगे बढ़े हैं. अब फ़्रंट-एंड डेवलपर के लिए, अपने काम में 3D यूज़र एक्सपीरियंस (UX) को शामिल करना पहले से ज़्यादा आसान हो गया है. इसके लिए, उन्हें कंप्यूटर ग्राफ़िक्स का पहले से अनुभव होना ज़रूरी नहीं है. Three.js, WebGL की सबसे लोकप्रिय लाइब्रेरी है. यह कई एक्सपैंशन के लिए बुनियाद के तौर पर काम करती है. इनमें react-three-fiber भी शामिल है, जो React फ़्रेमवर्क में 3D कॉम्पोनेंट जोड़ता है. अब Babylon.js या PlayCanvas जैसे वेब-आधारित गेम एडिटर भी उपलब्ध हैं. इनमें जाना-पहचाना इंटरफ़ेस और इंटिग्रेट किए गए टूलचेन मौजूद होते हैं.
हालांकि, इन लाइब्रेरी की मदद से बहुत काम किया जा सकता है, लेकिन बड़े प्रोजेक्ट में तकनीकी सीमाओं का सामना करना पड़ता है. ब्राउज़र पर गेमिंग के बारे में संदेह करने वाले लोग, यह बता सकते हैं कि JavaScript एक थ्रेड वाला और संसाधनों की कमी वाला प्रोग्राम है. हालांकि, इन सीमाओं को पार करने पर, आपको कई फ़ायदे मिलते हैं: कोई भी दूसरा प्लैटफ़ॉर्म, ब्राउज़र की मदद से तुरंत ऐक्सेस करने और ज़्यादातर डिवाइसों पर काम करने की सुविधा नहीं देता. ब्राउज़र की सुविधा वाले किसी भी सिस्टम पर, उपयोगकर्ता एक क्लिक में वीडियो चलाना शुरू कर सकते हैं. इसके लिए, उन्हें ऐप्लिकेशन इंस्टॉल करने और सेवाओं में साइन इन करने की ज़रूरत नहीं होती. इसके अलावा, डेवलपर को यूज़र इंटरफ़ेस (यूआई) बनाने या मल्टीप्लेयर मोड के लिए नेटवर्किंग को मैनेज करने के लिए, बेहतर फ़्रंट-एंड फ़्रेमवर्क का इस्तेमाल करने की सुविधा मिलती है. मेरी राय में, इन वैल्यू की वजह से ही ब्राउज़र, खिलाड़ियों और डेवलपर, दोनों के लिए एक बेहतरीन प्लैटफ़ॉर्म बन जाता है. साथ ही, Slow Roads के उदाहरण से पता चलता है कि तकनीकी सीमाओं को अक्सर डिज़ाइन की समस्या से कम किया जा सकता है.
धीमी सड़कों पर बेहतर परफ़ॉर्मेंस
स्लो रोड के मुख्य एलिमेंट में तेज़ी से चलने वाली गाड़ियां और महंगी जगहों की जानकारी शामिल होती है. इसलिए, डिज़ाइन के हर फ़ैसले को ध्यान में रखते हुए, मैंने यह पक्का किया कि ऐप्लिकेशन की परफ़ॉर्मेंस अच्छी हो. मेरी मुख्य रणनीति, गेमप्ले के ऐसे डिज़ाइन से शुरू करना था जिसमें कम से कम चीज़ें शामिल हों. इससे इंजन के आर्किटेक्चर में, संदर्भ के हिसाब से शॉर्टकट इस्तेमाल किए जा सकते थे. हालांकि, इसका मतलब है कि कम से कम सुविधाओं के लिए, कुछ ऐसी सुविधाओं को छोड़ना जो काम की हो सकती हैं. हालांकि, इससे एक ऐसा सिस्टम बनता है जो अलग-अलग ब्राउज़र और डिवाइसों पर बेहतर तरीके से काम करता है.
यहां उन मुख्य कॉम्पोनेंट के बारे में बताया गया है जिनकी वजह से Slow Roads का साइज़ कम रहता है.
गेमप्ले के हिसाब से एनवायरमेंट इंजन को आकार देना
गेम का मुख्य कॉम्पोनेंट होने के नाते, एनवायरमेंट जनरेशन इंजन की कीमत ज़्यादा होती है. इसलिए, मेमोरी और कंप्यूट के लिए बजट का ज़्यादातर हिस्सा इसी पर खर्च किया जाता है. यहां इस्तेमाल की गई ट्रिक, किसी समयावधि के दौरान भारी गणना को शेड्यूल और डिस्ट्रिब्यूट करने में है, ताकि परफ़ॉर्मेंस में होने वाले उतार-चढ़ाव से फ़्रेम रेट में रुकावट न आए.
एनवायरमेंट, ज्यामिति की टाइल से बना होता है. ये टाइल, साइज़ और रिज़ॉल्यूशन में अलग-अलग होती हैं. इन्हें "ज़्यादा जानकारी" या LoDs के तौर पर बांटा जाता है. यह इस बात पर निर्भर करता है कि ये कैमरे के कितने करीब दिखेंगी. आम तौर पर, फ़्री-रोमिंग कैमरे वाले गेम में, खिलाड़ी जहां भी जाए उसके आस-पास की जानकारी देने के लिए, अलग-अलग LoD को लगातार लोड और अनलोड करना पड़ता है. यह महंगा और बेकार काम हो सकता है, खास तौर पर तब, जब एनवायरमेंट अपने-आप डाइनैमिक तरीके से जनरेट होता है. हालांकि, 'धीमी सड़कें' विकल्प में इस कॉन्वेंशन को पूरी तरह से बदला जा सकता है. ऐसा, संदर्भ के हिसाब से यह उम्मीद करने की वजह से किया जा सकता है कि उपयोगकर्ता सड़क पर ही रहेगा. इसके बजाय, ज़्यादा जानकारी वाली ज्यामिति को सीधे रास्ते के बगल में मौजूद छोटे कॉरिडोर के लिए सुरक्षित रखा जा सकता है.

सड़क की मिडलाइन, खिलाड़ी के पहुंचने से काफ़ी पहले जनरेट हो जाती है. इससे यह सटीक अनुमान लगाया जा सकता है कि एनवायरमेंट की जानकारी कब और कहां की ज़रूरत होगी. इसकी वजह से, एक ऐसा सिस्टम बनता है जो ज़्यादा खर्च वाले काम को पहले से शेड्यूल कर सकता है. साथ ही, हर समय सिर्फ़ ज़रूरी जानकारी जनरेट करता है. साथ ही, ऐसी जानकारी पर समय बर्बाद नहीं करता जिसे कोई नहीं देखेगा. यह तकनीक सिर्फ़ इसलिए काम करती है, क्योंकि सड़क एक ऐसी है जिस पर कोई शाखा नहीं है. यह गेमप्ले के ऐसे समझौते का एक अच्छा उदाहरण है जो आर्किटेक्चरल शॉर्टकट के साथ काम करता है.

फ़िज़िक्स के नियमों के बारे में ज़्यादा जानकारी
एनवायरमेंट इंजन की गणना की मांग के बाद, भौतिकी सिम्युलेशन की मांग सबसे ज़्यादा होती है. Slow Roads, कस्टम और कम फ़िज़िक्स इंजन का इस्तेमाल करता है. यह उपलब्ध हर शॉर्टकट का इस्तेमाल करता है.
सबसे ज़्यादा बचत करने के लिए, सबसे पहले बहुत ज़्यादा ऑब्जेक्ट सिम्युलेट करने से बचें. इसके लिए, डाइनैमिक कॉलिज़न और नष्ट किए जा सकने वाले ऑब्जेक्ट जैसी चीज़ों को हटाकर, कम से कम और ज़ेन कॉन्टेक्स्ट का इस्तेमाल करें. यह मानते हुए कि वाहन सड़क पर ही रहेगा, इसका मतलब है कि सड़क से बाहर मौजूद ऑब्जेक्ट से होने वाली टक्कर को अनदेखा किया जा सकता है. इसके अलावा, सड़क को स्पैर्स मिडलाइन के तौर पर कोड करने से, सड़क की सतह और गार्ड रेलों से होने वाली टक्कर का तुरंत पता चलता है. यह सड़क के बीच से दूरी की जांच पर आधारित होता है. इसके बाद, ऑफ़-रोड ड्राइविंग ज़्यादा महंगी हो जाती है. हालांकि, यह गेमप्ले के संदर्भ में सही समझौते का एक और उदाहरण है.
मेमोरी फ़ुटप्रिंट को मैनेज करना
ब्राउज़र पर सीमित संसाधनों के इस्तेमाल की पाबंदी है. इसलिए, यह ज़रूरी है कि मेमोरी को ध्यान से मैनेज किया जाए. भले ही, JavaScript में गै़र-ज़रूरी डेटा को इकट्ठा करने की सुविधा उपलब्ध हो. इस बात को आसानी से अनदेखा किया जा सकता है, लेकिन गेम लूप में थोड़ी-बहुत नई मेमोरी का एलान करने पर, 60Hz पर गेम चलाने पर गंभीर समस्याएं आ सकती हैं. ज़्यादा ग़ैर-ज़रूरी डेटा इकट्ठा होने पर, उसे हटाने में कई फ़्रेम लग सकते हैं. इससे, उपयोगकर्ता के डिवाइस पर मल्टीटास्किंग करने पर, उसे रुकावटों का सामना करना पड़ सकता है. इससे बचने के लिए, शुरू करने पर क्लास वैरिएबल में लूप मेमोरी को पहले से तय किया जा सकता है और हर फ़्रेम में रीसाइकल किया जा सकता है.

यह भी बहुत ज़रूरी है कि ज़्यादा डेटा वाले स्ट्रक्चर, जैसे कि ज्यामिति और उनसे जुड़े डेटा बफ़र को किफ़ायती तरीके से मैनेज किया जाए. Slow Roads जैसे अनलिमिटेड जनरेट होने वाले गेम में, ज़्यादातर ज्यामिति एक तरह के ट्रेडमिल पर मौजूद होती है. जब कोई पुराना हिस्सा दूर हो जाता है, तो उसके डेटा स्ट्रक्चर को सेव किया जा सकता है और दुनिया के आने वाले हिस्से के लिए फिर से रीसाइकल किया जा सकता है. इसे ऑब्जेक्ट पूलिंग कहा जाता है.
इन तरीकों से, कोड को आसान बनाने के बजाय, कम से कम कोड का इस्तेमाल करके, एक्ज़ीक्यूशन को प्राथमिकता देने में मदद मिलती है. बेहतर परफ़ॉर्मेंस के मामले में, यह ध्यान रखना ज़रूरी है कि सुविधाएं, डेवलपर के फ़ायदे के लिए क्लाइंट से कैसे उधार लेती हैं. उदाहरण के लिए, Object.keys()
या Array.map()
जैसे तरीके काफ़ी आसान होते हैं. हालांकि, यह आसानी से अनदेखा किया जा सकता है कि हर तरीका अपनी रिटर्न वैल्यू के लिए एक नया ऐरे बनाता है. ऐसे ब्लैक-बॉक्स के काम करने के तरीके को समझने से, अपने कोड को बेहतर बनाने और परफ़ॉर्मेंस में होने वाले नुकसान से बचने में मदद मिल सकती है.
प्रोसेस के हिसाब से जनरेट की गई एसेट की मदद से, लोड होने में लगने वाला समय कम करना
गेम डेवलपर के लिए, रनटाइम की परफ़ॉर्मेंस सबसे ज़रूरी होती है. हालांकि, वेब पेज के लोड होने में लगने वाले समय से जुड़े सामान्य नियम अब भी लागू होते हैं. ज़्यादा डेटा वाला कॉन्टेंट जान-बूझकर ऐक्सेस करने पर, उपयोगकर्ता ज़्यादा सहनशील हो सकते हैं. हालांकि, अगर उपयोगकर्ता को बनाए रखने में कोई समस्या नहीं आ रही है, तो भी लोड होने में लगने वाला ज़्यादा समय, उपयोगकर्ता अनुभव पर बुरा असर डाल सकता है. गेम में अक्सर टेक्सचर, साउंड, और 3D मॉडल के तौर पर बड़ी एसेट की ज़रूरत होती है. साथ ही, जहां भी ज़रूरत न हो वहां इन्हें कम से कम ध्यान से कम किया जाना चाहिए.
इसके अलावा, क्लाइंट पर एसेट को प्रोसेस के हिसाब से जनरेट करने से, लंबे समय तक ट्रांसफ़र होने से बचा जा सकता है. इससे, धीमे इंटरनेट कनेक्शन का इस्तेमाल करने वाले उपयोगकर्ताओं को काफ़ी फ़ायदा मिलता है. साथ ही, डेवलपर को अपने गेम को बनाने के तरीके पर ज़्यादा कंट्रोल मिलता है. यह कंट्रोल, गेम को लोड करने के शुरुआती चरण के लिए ही नहीं, बल्कि अलग-अलग क्वालिटी सेटिंग के लिए जानकारी के लेवल को अडैप्ट करने के लिए भी मिलता है.
'धीमी सड़कें' में मौजूद ज़्यादातर ज्यामिति, प्रोसेस के हिसाब से जनरेट की जाती है और आसान होती है. साथ ही, ज़्यादा जानकारी देने के लिए कस्टम शेडर, कई टेक्सचर को जोड़ते हैं. हालांकि, इनका एक नुकसान यह है कि ये टेक्स्चर ज़्यादा जगह घेर सकते हैं. हालांकि, यहां बचत करने के और भी अवसर हैं. जैसे, स्टोकेस्टिक टेक्स्चरिंग का इस्तेमाल करके, छोटे सोर्स टेक्स्चर से ज़्यादा जानकारी हासिल की जा सकती है. ज़्यादा बेहतर टेक्स्टर बनाने के लिए, texgen.js जैसे टूल का इस्तेमाल करके, क्लाइंट पर ही टेक्स्टर जनरेट किए जा सकते हैं. ऑडियो के लिए भी यही बात लागू होती है. Web Audio API की मदद से, ऑडियो नोड की मदद से साउंड जनरेट किया जा सकता है.
प्रोसेस्युरल ऐसेट की मदद से, शुरुआती एनवायरमेंट जनरेट करने में औसतन सिर्फ़ 3.2 सेकंड लगते हैं. डाउनलोड किए जाने वाले छोटे साइज़ का ज़्यादा से ज़्यादा फ़ायदा पाने के लिए, नए लोगों को एक स्प्लैश स्क्रीन दिखती है. साथ ही, ज़्यादा डेटा खर्च करने वाले सीन को शुरू करने की प्रोसेस को तब तक के लिए रोक दिया जाता है, जब तक कि उपयोगकर्ता 'हां' बटन को दबाकर सहमति नहीं देता. यह बाउंस हुए सेशन के लिए भी एक आसान बफ़र के तौर पर काम करता है. इससे डाइनैमिक तौर पर लोड होने वाली एसेट के ट्रांसफ़र में होने वाली बर्बादी कम हो जाती है.
देर से ऑप्टिमाइज़ेशन के लिए बेहतर सुविधाएं
मैंने हमेशा से ही, स्लो रोड के कोडबेस को एक्सपेरिमेंट के तौर पर देखा है. इसलिए, मैंने इसे डेवलप करने के लिए, तेज़ी से बदलाव करने का तरीका अपनाया है. जटिल और तेज़ी से बदलते सिस्टम आर्किटेक्चर के साथ काम करते समय, यह अनुमान लगाना मुश्किल हो सकता है कि कहां ज़रूरी रुकावटें आ सकती हैं. ध्यान, सिस्टम को पूरी तरह से ठीक करने के बजाय, ज़रूरी सुविधाओं को तेज़ी से लागू करने पर होना चाहिए. इसके बाद, उन सिस्टम को ऑप्टिमाइज़ करने पर ध्यान देना चाहिए जिनमें ये सुविधाएं ज़रूरी हैं. इस चरण के लिए, Chrome DevTools में मौजूद परफ़ॉर्मेंस प्रोफ़ाइलर का इस्तेमाल करना बहुत ज़रूरी है. इसकी मदद से, मुझे गेम के पुराने वर्शन से जुड़ी कुछ बड़ी समस्याओं का पता लगाने में मदद मिली. डेवलपर के तौर पर आपका समय बहुत अहम है. इसलिए, पक्का करें कि आप ऐसी समस्याओं पर समय बर्बाद न कर रहे हों जो मामूली या ग़ैर-ज़रूरी साबित हो सकती हैं.
उपयोगकर्ता अनुभव की निगरानी करना
इन सभी तरकीबों को लागू करते समय, यह पक्का करना ज़रूरी है कि गेम, उम्मीद के मुताबिक काम करे. किसी भी गेम को डेवलप करने के लिए, हार्डवेयर की अलग-अलग क्षमताओं को ध्यान में रखना ज़रूरी होता है. हालांकि, वेब गेम में ज़्यादा डिवाइसों को टारगेट किया जा सकता है. इनमें, एक साथ टॉप-एंड डेस्कटॉप और 10 साल पुराने मोबाइल डिवाइस, दोनों शामिल हैं. इसका सबसे आसान तरीका यह है कि आप अपने कोडबेस में सबसे ज़्यादा रुकावटों को ठीक करने के लिए सेटिंग उपलब्ध कराएं. ये सेटिंग, जीपीयू और सीपीयू, दोनों के ज़्यादा काम करने वाले टास्क के लिए होनी चाहिए. इन सेटिंग के बारे में, आपको प्रोफ़ाइलर से पता चलता है.
अपनी मशीन पर प्रोफ़ाइल बनाने से, सिर्फ़ इतना ही पता चलता है. इसलिए, अपने उपयोगकर्ताओं से किसी तरह फ़ीडबैक पाना ज़रूरी है. 'धीमी सड़कें' के लिए, मैं आसान आंकड़ों का इस्तेमाल करता हूं. इन आंकड़ों से, परफ़ॉर्मेंस के साथ-साथ स्क्रीन रिज़ॉल्यूशन जैसे कॉन्टेक्स्ट फ़ैक्टर की जानकारी मिलती है. ये आंकड़े, socket.io का इस्तेमाल करके किसी बुनियादी Node बैकएंड पर भेजे जाते हैं. साथ ही, इनमें गेम में मौजूद फ़ॉर्म के ज़रिए सबमिट किए गए लिखित सुझाव/राय/शिकायत/राय भी शामिल होती है. शुरुआती दिनों में, इन आंकड़ों से कई अहम समस्याओं का पता चला. इन समस्याओं को यूज़र एक्सपीरियंस (यूएक्स) में छोटे-मोटे बदलाव करके ठीक किया जा सकता था. जैसे, लगातार कम फ़्रेम रेट का पता चलने पर सेटिंग मेन्यू को हाइलाइट करना या चेतावनी देना कि परफ़ॉर्मेंस काफ़ी खराब होने पर, उपयोगकर्ता को हार्डवेयर ऐक्सेलरेशन चालू करना पड़ सकता है.
आगे की मुश्किल राहें
इन सभी तरीकों का इस्तेमाल करने के बाद भी, गेम खेलने वाले लोगों में से एक बड़ा हिस्सा कम सेटिंग पर गेम खेलता है. खास तौर पर, वे लोग जो कम साइज़ वाले ऐसे डिवाइसों का इस्तेमाल करते हैं जिनमें जीपीयू नहीं होता. क्वालिटी सेटिंग की उपलब्ध रेंज की वजह से, परफ़ॉर्मेंस का बंटवारा काफ़ी बराबर होता है. हालांकि, सिर्फ़ 52% खिलाड़ियों को 55 FPS से ज़्यादा की परफ़ॉर्मेंस मिलती है.

अच्छी बात यह है कि परफ़ॉर्मेंस में सुधार करके, अब भी बचत करने के कई अवसर हैं. जीपीयू की मांग को कम करने के लिए, रेंडरिंग से जुड़ी और तरकीबें जोड़ी जा रही हैं. साथ ही, मुझे उम्मीद है कि आने वाले समय में, हम वेब वर्कर्स की मदद से, एनवायरमेंट जनरेशन को पैरलल कर पाएंगे. साथ ही, कोडबेस में WASM या WebGPU को शामिल करने की ज़रूरत पड़ सकती है. अगर मुझे ज़्यादा जगह मिलती है, तो बेहतर और अलग-अलग तरह के एनवायरमेंट बनाए जा सकेंगे. यह प्रोजेक्ट के बाकी हिस्से के लिए हमारा लक्ष्य रहेगा.
शौक के प्रोजेक्ट के तौर पर, Slow Roads ने यह दिखाने में काफ़ी मदद की है कि ब्राउज़र गेम कितने बेहतर, लोकप्रिय, और बेहतरीन परफ़ॉर्म करने वाले हो सकते हैं. अगर मैंने WebGL में आपकी दिलचस्पी बढ़ाने में कामयाबी हासिल की है, तो आपको यह जानना चाहिए कि तकनीकी तौर पर, स्लो रोड्स इसकी पूरी क्षमताओं का एक छोटा सा उदाहरण है. हमारा सुझाव है कि पाठक Three.js शोकेस को एक्सप्लोर करें. साथ ही, वेब गेम डेवलपमेंट में दिलचस्पी रखने वाले लोग, webgamedev.com पर जाकर कम्यूनिटी में शामिल हो सकते हैं.