नमस्ते! मैं व्लादिमीर पोपोव, वॉर रोबोट्स प्रोजेक्ट का क्लाइंट डेवलपर हूं। लेखन के समय, वॉर रोबोट कई वर्षों से मौजूद हैं, और इस दौरान गेम में दर्जनों नए गेम सामने आए हैं। स्वाभाविक रूप से, रोबोट की विविध क्षमताएं महत्वपूर्ण हैं, क्योंकि उनके बिना, रोबोट अपनी विशिष्टता खो देते हैं जो खेल को और अधिक रोचक बना देता है।
इस पोस्ट में, मैं साझा करूंगा कि हमारे गेम में गेमप्ले क्षमता प्रणाली कैसे काम करती है - और यह कैसे विकसित हुई है। और, चीजों को अधिक सुलभ बनाने के लिए, मैं चीजों को सरल शब्दों में और बहुत अधिक तकनीकी विवरण के बिना समझाऊंगा।
सबसे पहले, आइए परियोजना के इतिहास पर गौर करें और पुराने कार्यान्वयन को देखें जिसका अब उपयोग नहीं किया जा रहा है।
पहले, क्षमताओं को बहुत ही तुच्छ तरीके से डिज़ाइन किया गया था: उनके पास एक घटक था जो रोबोट से जुड़ा हुआ था। यह एक ऐसा निर्माण था जहां प्रोग्रामर ने पूरी तरह से वर्णन किया कि क्षमता कैसे काम करती है: इसका प्रवाह और यह अन्य क्षमताओं के साथ कैसे इंटरैक्ट करता है। सभी तर्क एक घटक के अंदर वर्णित हैं, और गेम डिजाइनर इसे आसानी से रोबोट से जोड़ सकता है और आवश्यकतानुसार पैरामीटर कॉन्फ़िगर कर सकता है। यह उल्लेखनीय है कि क्षमताओं के प्रवाह को बदलना संभव नहीं था - गेम डिजाइनर केवल पैरामीटर और समय बदल सकते थे।
एक पुरानी क्षमता केवल दो अवस्थाओं में मौजूद हो सकती है: सक्रिय और निष्क्रिय, और प्रत्येक राज्य को अपनी कार्रवाई सौंपी जा सकती है।
आइए "जैमर" क्षमता का एक उदाहरण देखें, जो पहले रोबोट "स्टॉकर" के पास थी; इसने इस तरह काम किया:
लंबे समय तक, यह कार्यक्षमता हमारे लिए पर्याप्त थी, लेकिन समय के साथ गेम डिजाइनर और प्रोग्रामर दोनों इस दृष्टिकोण से संतुष्ट नहीं थे: प्रोग्रामर के लिए इन क्षमताओं का समर्थन करना मुश्किल था क्योंकि कोड राक्षसी हो गया था; इसमें एक बहुत लंबी विरासत श्रृंखला शामिल थी, जहां हर स्थिति का वर्णन किया जाना था। इसके अतिरिक्त, गेम डिजाइनरों में लचीलेपन की कमी थी - किसी क्षमता में कोई भी बदलाव करने के लिए, उन्हें प्रोग्रामर से संशोधन का आदेश देना पड़ता था, भले ही आसन्न क्षमता में समान कार्यक्षमता हो।
तो, हमें एहसास हुआ कि कुछ बदलने की जरूरत है। इसलिए, हमने एक नई प्रणाली विकसित की, जहां प्रत्येक क्षमता को कई संबंधित वस्तुओं के एक सेट के रूप में दर्शाया गया था। कार्यक्षमता को राज्य क्षमताओं और राज्य घटकों में विभाजित किया गया था।
यह कैसे काम करता है? प्रत्येक योग्यता का एक मुख्य उद्देश्य होता है। यह केंद्रीय वस्तु अन्य क्षमता वाली वस्तुओं को बाहरी दुनिया से जोड़ती है, और इसके विपरीत; यह सभी मुख्य निर्णय भी लेता है।
राज्यों की संख्या कोई भी हो सकती है. अनिवार्य रूप से, इस पुनरावृत्ति की स्थिति पुराने संस्करण में सक्रिय/निष्क्रिय स्थितियों से बहुत अलग नहीं है, लेकिन अब उनमें से कोई भी संख्या हो सकती है, और उनका उद्देश्य अधिक सारगर्भित हो गया है। हम ध्यान देंगे कि एक क्षमता में एक समय में केवल एक ही अवस्था सक्रिय हो सकती है।
पुरानी प्रणाली की तुलना में मुख्य नवाचार घटक थे: एक घटक कुछ कार्रवाई का वर्णन करता है, और प्रत्येक राज्य में किसी भी संख्या में घटक हो सकते हैं।
नई क्षमताएं कैसे काम करती हैं? कोई क्षमता केवल किसी एक अवस्था में हो सकती है; मुख्य वस्तु उन्हें बदलने के लिए जिम्मेदार है। किसी राज्य से जुड़ने वाले घटक राज्य के सक्रियण/निष्क्रिय होने पर प्रतिक्रिया करते हैं और, इसके आधार पर, या तो कुछ कार्रवाई करना शुरू कर सकते हैं या इसे करना बंद कर सकते हैं।
सभी वस्तुएँ अनुकूलन योग्य हो गई हैं; एक गेम डिज़ाइनर राज्यों और घटकों को अपनी इच्छानुसार मिश्रित कर सकता है, इस प्रकार पूर्व-स्थापित ब्लॉकों से एक नई क्षमता तैयार कर सकता है। अब, प्रोग्रामर को एक नया घटक या स्थिति बनाने के लिए केवल चित्र दर्ज करने की आवश्यकता होती है, जिससे कोड लिखना बहुत आसान हो जाता है: वे छोटी इकाइयों के साथ काम करते हैं, कुछ सरल तत्वों का वर्णन करते हैं, और अब स्वयं क्षमता का निर्माण नहीं करते हैं - गेम डिजाइनर अब ऐसा करते हैं।
प्रवाह इस प्रकार हो गया है:
इसके बाद यह प्रक्रिया बार-बार दोहराई जाती है। उपयोग में आसानी के लिए, एक राज्य न केवल एक घटक कंटेनर के रूप में कार्य करता है, यह यह भी निर्धारित करता है कि दूसरे राज्य में कब स्विच करना है और मुख्य ऑब्जेक्ट से स्विच करने का अनुरोध करता है। समय के साथ, यह अभी भी हमारे लिए पर्याप्त नहीं निकला, और क्षमता आरेख निम्नलिखित में बदल गया:
मुख्य वस्तु, अवस्था और घटक अपने स्थान पर रहे, लेकिन नये तत्व भी जुड़ गये।
पहली चीज़ जो आपकी नज़र में आती है वह यह है कि हमने प्रत्येक राज्य और घटक में शर्तें जोड़ी हैं: राज्यों के लिए, ये राज्य छोड़ने के लिए अतिरिक्त आवश्यकताओं को परिभाषित करते हैं; घटकों के लिए, वे यह निर्धारित करते हैं कि घटक अपना कार्य कर सकता है या नहीं।
चार्ज कंटेनर में शुल्क शामिल होते हैं, उन्हें रिचार्ज किया जाता है, यदि आवश्यक हो तो रिचार्ज करना बंद कर दिया जाता है और राज्यों को उपयोग के लिए शुल्क प्रदान किया जाता है।
टाइमर का उपयोग तब किया जाता है जब कई राज्यों के पास एक सामान्य निष्पादन समय होना चाहिए, लेकिन उनका अपना निष्पादन समय परिभाषित नहीं है।
यह ध्यान रखना महत्वपूर्ण है कि सभी क्षमता वाली वस्तुएं वैकल्पिक हैं। तकनीकी रूप से, कार्य करने की क्षमता के लिए केवल एक मुख्य वस्तु और एक अवस्था की आवश्यकता होती है।
अब, जबकि वास्तव में प्रोग्रामर की भागीदारी के बिना पूरी तरह से निर्मित कई क्षमताएं नहीं हैं, सामान्य तौर पर विकास काफी सस्ता हो गया है, क्योंकि प्रोग्रामर को अब केवल बहुत छोटी चीजें लिखने की जरूरत है: उदाहरण के लिए, एक नया राज्य या दो घटक - बाकी पुन: उपयोग किया जाता है.
आइए हमारी क्षमताओं के घटकों को संक्षेप में प्रस्तुत करें:
मुख्य वस्तु एक राज्य मशीन के कार्य करती है। यह राज्यों और घटकों को दुनिया के बारे में जानकारी प्रदान करता है और दुनिया को क्षमताओं के बारे में जानकारी प्रदान करता है। मुख्य वस्तु राज्यों, घटकों और क्षमता के सेवा भागों के बीच एक कड़ी के रूप में कार्य करती है: शुल्क और बाहरी टाइमर।
राज्य मुख्य ऑब्जेक्ट से सक्रियण और निष्क्रियकरण आदेशों को सुनता है और तदनुसार, घटकों को सक्रिय और निष्क्रिय करता है, और मुख्य ऑब्जेक्ट को दूसरे राज्य में स्विच करने का भी अनुरोध करता है। राज्य निर्धारित करता है कि उसे कब अगले पर स्विच करने की आवश्यकता है; ऐसा करने के लिए, यह अपनी आंतरिक स्थिति का उपयोग करता है: क्या खिलाड़ी ने क्षमता बटन पर क्लिक किया है, क्या राज्य के सक्रिय होने के बाद एक निश्चित समय बीत चुका है, और इसी तरह, और राज्य से जुड़ी बाहरी स्थितियां।
घटक राज्य से सक्रियण और निष्क्रियकरण आदेशों को सुनता है और कुछ कार्रवाई करता है: अलग या दीर्घकालिक। क्रियाएँ पूरी तरह से भिन्न हो सकती हैं: वे क्षति पहुँचा सकते हैं, किसी सहयोगी को ठीक कर सकते हैं, एनीमेशन चालू कर सकते हैं, इत्यादि।
शर्त यह जांचती है कि वांछित तत्व किस स्थिति में है और इसकी रिपोर्ट राज्य या घटक को देती है। स्थितियाँ जटिल हो सकती हैं. यदि शर्त पूरी नहीं होती है तो कोई राज्य दूसरे राज्य में संक्रमण का अनुरोध नहीं करता है। शर्त पूरी न होने पर घटक भी कोई कार्रवाई नहीं करता है। शर्तें एक वैकल्पिक इकाई हैं; हर क्षमता उनके पास नहीं होती.
चार्ज कंटेनर शुल्क रखता है, उन्हें रिचार्ज करता है, आवश्यकता पड़ने पर रिचार्ज करना बंद कर देता है और राज्यों को शुल्क प्रदान करता है। इसका उपयोग मल्टी-चार्ज क्षमताओं में किया जाता है, जब आपको खिलाड़ी को इसे कई बार उपयोग करने की अनुमति देने की आवश्यकता होती है, लेकिन लगातार n बार से अधिक नहीं।
टाइमर का उपयोग तब किया जाता है जब कई राज्यों में एक समान अवधि होती है, लेकिन यह ज्ञात नहीं है कि उनमें से प्रत्येक कितने समय तक चलेगा। कोई भी राज्य n सेकंड के लिए टाइमर शुरू कर सकता है। सभी प्रासंगिक राज्य टाइमर समाप्ति ईवेंट की सदस्यता लेते हैं और इसके समाप्त होने पर कुछ करते हैं।
अब आइए क्षमता आरेख पर वापस लौटें। इसकी कार्यक्षमता कैसे बदली?
राज्य अतिरिक्त संक्रमण शर्त के रूप में शुल्क का उपयोग कर सकते हैं। यदि ऐसा संक्रमण होता है, तो आवेशों की संख्या कम हो जाती है। राज्य एक सामान्य टाइमर का भी उपयोग कर सकते हैं। इस मामले में, उनके निष्पादन का कुल समय एक टाइमर द्वारा निर्धारित किया जाएगा, और प्रत्येक राज्य व्यक्तिगत रूप से किसी भी समय तक चल सकता है।
हमने नई क्षमता वाले यूआई के लिए पहिए का पूरी तरह से आविष्कार नहीं किया।
मुख्य ऑब्जेक्ट का अपना यूआई है। यह कुछ तत्वों को परिभाषित करता है जो हमेशा यूआई में होने चाहिए और जो वर्तमान में सक्रिय स्थिति पर निर्भर नहीं होते हैं।
यूआई में प्रत्येक राज्य की अपनी जोड़ी होती है, और राज्य यूआई केवल तभी प्रदर्शित होता है जब उसका राज्य सक्रिय होता है। यह अपनी स्थिति के बारे में डेटा प्राप्त करता है और इसे एक या दूसरे तरीके से प्रदर्शित कर सकता है। उदाहरण के लिए, अवधि वाले राज्यों के यूआई में आमतौर पर एक बार और टेक्स्ट होता है जो शेष समय प्रदर्शित करता है।
ऐसे मामले में जहां राज्य किसी क्षमता को जारी रखने के लिए बाहरी कमांड की प्रतीक्षा कर रहा है, इसका यूआई एक बटन प्रदर्शित करता है, और इसे दबाने पर राज्य को कमांड भेजता है।
हम विशिष्ट उदाहरणों का उपयोग करके देखेंगे कि योग्यताएँ कैसे काम करती हैं; सबसे पहले, आइए "इनक्विज़िटर" नामक रोबोट को देखें। हमारे पास चार राज्य हैं जो एक दूसरे का अनुसरण करते हैं - राज्यों के ऊपर आप यूआई में उनका प्रदर्शन देख सकते हैं। उनमें से दो के लिए, हम उन घटकों को भी देखते हैं जो उनसे संबंधित हैं; अन्य दो राज्यों में घटक ही नहीं हैं।
यहाँ क्षमता का प्रवाह है:
यह सब "WaitForClick" स्थिति से शुरू होता है। इस समय क्षमता कुछ नहीं करती; यह सिर्फ आदेशों की प्रतीक्षा करता है।
जैसे ही ऐसा आदेश प्राप्त होता है, मुख्य वस्तु स्थिति बदल देती है। अगली सक्रिय स्थिति "WaitForGrounded" है।
इस स्थिति में कुछ घटक होते हैं, और इसलिए, सक्रिय होने पर, रोबोट कूदता है और ध्वनि और एनीमेशन चलाता है। अन्य बातों के अलावा, जब राज्य सक्रिय होता है, तो रोबोट जैमर प्रभाव से प्रभावित होता है, जो रोबोट पर निशाना साधने पर रोक लगाता है।
जब रोबोट उतरता है, तो उसकी क्षमता अगली अवस्था में चली जाती है।
इस स्थिति में तीन घटक होते हैं: पहले से ही परिचित ध्वनि और जैमर, साथ ही शेक, जिसके कारण n के दायरे में सभी खिलाड़ियों के लिए कैमरा हिल जाता है।
चूँकि इस अवस्था में अवधि है, यह n सेकंड के लिए काम करती है, फिर क्षमता अगली अवस्था में चली जाती है।
अंतिम स्थिति भी एक अवधि के साथ आती है, लेकिन इसमें कोई घटक नहीं होता है: यह नियमित रूप से ठंडा होता है।
पूरा होने पर, क्षमता पहली स्थिति में वापस आ जाती है।
एक अन्य उदाहरण "फैंटम" है। यह काफी हद तक इनक्विसिटर जैसा है, लेकिन इसमें कुछ बारीकियां हैं:
हम waitForClick से शुरुआत करते हैं।
फिर, अवधि, जिसमें टेलीपोर्ट स्थापित है, मेच के आँकड़े बदल दिए जाते हैं, और ध्वनि और एनीमेशन चलाए जाते हैं।
इसके बाद: ड्यूरेशनऑरक्लिक, जिसमें मेच के आँकड़े बदले जाते हैं, एनीमेशन और एफएक्स चलाए जाते हैं।
यदि एक क्लिक किया गया था, तो हम दूसरी अवधि पर जाते हैं, जिसमें मेच टेलीपोर्ट, आँकड़े बदलते हैं, और एनीमेशन, एफएक्स और ध्वनियाँ बजाई जाती हैं।
इस स्थिति के बाद (या ड्यूरेशनऑरक्लिक के लिए समय समाप्त होने के बाद), हम ड्यूरेशन की ओर बढ़ते हैं।
यहां मुख्य अंतर यह है कि हम ब्रांचिंग वाले राज्यों को देखते हैं: यदि निर्दिष्ट समय बीत चुका है तो ड्यूरेशनऑरक्लिक राज्य ए में जाता है, या यदि खिलाड़ी ने पहले क्षमता बटन दबाया है तो बी राज्य में जाता है।
हालांकि ऐसा प्रतीत होता है कि हमारा सिस्टम कुछ सरल से काफी जटिल तक विकसित हुआ है, इस बदलाव ने प्रोग्रामर और गेम डिजाइनर दोनों के जीवन को सरल बना दिया है। अब ज्यादातर छोटे घटकों को जोड़ते समय प्रोग्रामर की सहायता की आवश्यकता होती है, जबकि टीम के सदस्यों के बाद वाले समूह ने अधिक स्वायत्तता प्राप्त कर ली है और अब स्वतंत्र रूप से मौजूदा राज्यों और घटकों से नई क्षमताओं को इकट्ठा कर सकते हैं। एक अन्य बोनस के रूप में, उसी समय, खिलाड़ियों को मेच की अधिक विविध और जटिल क्षमताओं के रूप में लाभ भी प्राप्त हुआ।