डेटा चालित कोडिंग
आपके द्वारा उल्लिखित प्रत्येक चीज एक ऐसी चीज़ है जिसे डेटा में निर्दिष्ट किया जा सकता है। क्यों लोड कर रहे हो aspecificmap
? क्योंकि गेम कॉन्फ़िगरेशन यह कहता है कि जब खिलाड़ी किसी नए गेम की शुरुआत करता है, तो यह पहला स्तर होता है, या इसलिए कि खिलाड़ी की सेव फ़ाइल में करंट सेव पॉइंट का नाम वे सिर्फ लोड करते हैं, आदि।
तुम कैसे खोजोगे aspecificmap
? क्योंकि यह एक डेटा फ़ाइल में है जो मैप आईडी और उनके ऑन-डिस्क संसाधनों को सूचीबद्ध करता है।
केवल "कोर" संसाधनों का एक विशेष रूप से छोटा सेट होना चाहिए जो हार्ड-कोडिंग से बचने के लिए वैध रूप से कठिन या असंभव हो। थोड़े से काम के साथ, यह एकल हार्ड-कोडित डिफ़ॉल्ट एसेट नाम जैसे main.wad
या पसंद तक सीमित हो सकता है । इस फ़ाइल को संभवतः गेम, उर्फ में कमांड-लाइन तर्क पास करके रनटाइम में बदला जा सकता है game.exe -wad mymain.wad
।
डेटा-संचालित कोड लिखना कुछ अन्य सिद्धांतों पर निर्भर करता है। उदाहरण के लिए, सिस्टम या मॉड्यूल किसी विशेष संसाधन के लिए पूछने से बच सकते हैं और इसके बजाय उन निर्भरताओं को उल्टा कर सकते हैं। अर्थात्, इसके प्रारंभ कोड में DebugDrawer
लोड न करें debug.font
; इसके बजाय, DebugDrawer
इसके प्रारंभ कोड में संसाधन संभाल लें। उस हैंडल को मुख्य गेम कॉन्फ़िगरेशन फ़ाइल से लोड किया जा सकता है।
हमारे कोडबेस से एक ठोस उदाहरण के रूप में, हमारे पास एक "वैश्विक डेटा" ऑब्जेक्ट है जो संसाधन डेटाबेस से लोड किया गया है (जो स्वयं ./resources
फ़ोल्डर डिफ़ॉल्ट रूप से है, लेकिन कमांड लाइन तर्क के साथ अतिभारित किया जा सकता है)। इस वैश्विक डेटा का संसाधन डेटाबेस आईडी कोडबेस में एकमात्र आवश्यक हार्ड-कोडेड संसाधन नाम है (हमारे पास अन्य हैं क्योंकि कभी-कभी प्रोग्रामर आलसी हो जाते हैं, लेकिन हम आम तौर पर अंततः उन फिक्सिंग / हटाने को समाप्त कर देते हैं)। यह वैश्विक डेटा ऑब्जेक्ट उन घटकों से भरा है जिनका एकमात्र उद्देश्य कॉन्फ़िगरेशन डेटा प्रदान करना है। घटक में से एक यूआई ग्लोबल डेटा घटक है जिसमें कई अन्य कॉन्फ़िगरेशन आइटमों के बीच सभी मुख्य यूआई संसाधनों (फोंट, फ्लैश फाइलें, आइकन, स्थानीयकरण डेटा, आदि) के लिए संसाधन हैंडल शामिल हैं। जब कोई UI डेवलपर मुख्य UI संपत्ति का नाम बदलने का निर्णय लेता /ui/mainmenu.swf
है/ui/lobby.swf
वे सिर्फ उस वैश्विक डेटा संदर्भ को अपडेट करते हैं; किसी भी इंजन कोड को बदलने की जरूरत नहीं है।
हम इस वैश्विक डेटा का उपयोग हर चीज के लिए करते हैं। सभी खेलने योग्य वर्ण, सभी स्तर, UI, ऑडियो, कोर संपत्ति, नेटवर्क कॉन्फ़िगरेशन, सब कुछ। (ठीक है, सब कुछ नहीं , लेकिन उन अन्य चीजों को तय किया जाना चाहिए।)
इस दृष्टिकोण के कई अन्य फायदे हैं। एक के लिए, यह संसाधन पैकिंग और बंडल को पूरी प्रक्रिया से अभिन्न बनाता है। इंजन में हार्ड-कोडिंग पथ का मतलब यह भी है कि उन्हीं रास्तों को हार्ड-कोडेड किया जाना चाहिए जो कि स्क्रिप्ट या टूल में खेल की संपत्ति को पैकेज करते हैं, और उन रास्तों को फिर सिंक से बाहर निकाला जा सकता है। इसके बजाय एक ही कोर एसेट और रेफरेंस चेन पर निर्भर रहने से, हम एक सिंगल कमांड के साथ एक एसेट बंडल बना सकते हैं bundle.exe -root config.data -out main.wad
और यह जान सकते हैं कि इसमें वे सभी एसेट शामिल होंगे जिनकी हमें आवश्यकता है। इसके अलावा, चूंकि बंडलर केवल संसाधन संदर्भों का पालन कर रहा है, इसलिए हम जानते हैं कि इसमें केवल उन संपत्तियों को शामिल किया जाएगा जिनकी हमें आवश्यकता है और सभी बचे हुए फुलफलों को छोड़ दें जो अनिवार्य रूप से एक परियोजना के जीवन पर जमा होते हैं (प्लस हम स्वचालित रूप से उस की सूची उत्पन्न कर सकते हैं प्रूनिंग के लिए फुलाना)।
इस पूरी बात का एक कोना कोना लिपियों में है। इंजन डेटा-संचालित करना आसान है, लेकिन यह वैचारिक रूप से आसान है, लेकिन मैंने बहुत सारे प्रोजेक्ट्स (एएए के शौक) देखे हैं, जहां स्क्रिप्ट्स को डेटा माना जाता है और इसलिए केवल संसाधन पथों का अंधाधुंध उपयोग करने के लिए "अनुमति" दी जाती है। ऐसा मत करो। अगर किसी Lua फ़ाइल को एक संसाधन की आवश्यकता होती है और यह सिर्फ एक फ़ंक्शन को कॉल करती है, जैसे textures.lua("/path/to/texture.png")
कि परिसंपत्ति पाइपलाइन को यह जानने में बहुत परेशानी होती है कि स्क्रिप्ट को /path/to/texture.png
सही ढंग से संचालित करने की आवश्यकता है और उस बनावट को अप्रयुक्त और अनावश्यक मान सकता है। लिपियों को किसी अन्य कोड की तरह माना जाना चाहिए: संसाधनों या तालिकाओं सहित किसी भी डेटा को कॉन्फ़िगरेशन प्रविष्टि में निर्दिष्ट किया जाना चाहिए जिसे इंजन और संसाधन पाइपलाइन निर्भरता के लिए निरीक्षण कर सकते हैं। इसके foo.lua
बजाय "लोड स्क्रिप्ट " कहने वाले डेटा को कहना चाहिए "foo.lua
और इसे ये मानदंड दें "जहां मापदंडों में आवश्यक कोई भी संसाधन शामिल हैं। यदि कोई स्क्रिप्ट उदाहरण के लिए दुश्मनों को बेतरतीब ढंग से जगाती है, तो उस कॉन्फ़िगरेशन फ़ाइल से स्क्रिप्ट में संभावित दुश्मनों की सूची पास करें। इंजन तब स्तर के साथ दुश्मनों को पूर्व-लोड कर सकता है ( चूंकि यह संभावित स्पॉन की पूरी सूची जानता है) और संसाधन पाइपलाइन खेल के साथ सभी दुश्मनों को बंडल करना जानता है (क्योंकि वे निश्चित रूप से कॉन्फ़िगरेशन डेटा द्वारा संदर्भित हैं)। यदि स्क्रिप्ट पथ नामों के तार उत्पन्न करती है और बस एक load
फ़ंक्शन को कॉल करती है इंजन और न ही संसाधन पाइपलाइन में विशेष रूप से यह जानने का कोई तरीका है कि स्क्रिप्ट को लोड करने के लिए कौन सी संपत्ति की कोशिश हो सकती है।