डिकॉयिंग / सूचना छिपाने के लिए एंटिटी-कंपोनेंट सिस्टम भयानक नहीं है?


11

शीर्षक जानबूझकर अतिशयोक्तिपूर्ण है और यह सिर्फ पैटर्न के साथ मेरी अनुभवहीनता हो सकती है लेकिन यहाँ मेरा तर्क है:

संस्थाओं को लागू करने का "सामान्य" या यकीनन सीधा तरीका उन्हें वस्तुओं के रूप में लागू करना और सामान्य व्यवहार को उपवर्गित करना है। की क्लासिक समस्या के लिए यह होता है "एक है EvilTreeकी एक उपवर्ग Treeया Enemy?"। यदि हम कई विरासत की अनुमति देते हैं, तो हीरे की समस्या पैदा होती है। हम इसके बजाय संयुक्त कार्यप्रणाली को आगे बढ़ा सकते हैं Treeऔर Enemyआगे चलकर पदानुक्रम को बढ़ा सकते हैं जो ईश्वर वर्गों की ओर जाता है, या हम जानबूझकर अपने Treeऔर Entityकक्षाओं में व्यवहार को छोड़ सकते हैं (उन्हें चरम मामले में इंटरफेस बना EvilTreeसकते हैं ) ताकि खुद को लागू किया जा सके - जो आगे बढ़ता है कोड दोहराव अगर हम कभी भी एक SomewhatEvilTree

इकाई-घटक प्रणाली को विभाजित करके इस समस्या को हल करने का प्रयास करें Treeऔर Enemyविभिन्न घटकों में वस्तु - कहते हैं Position, Healthऔर AI- और लागू इस तरह के एक के रूप में प्रणाली, AISystemकि ऐ निर्णय के अनुसार एक Entitiy की स्थिति बदल जाती है। अब तक तो अच्छा है लेकिन क्या हो EvilTreeसकता है अगर कोई पॉवरअप उठा सकता है और नुकसान का सामना कर सकता है? पहले हमें एक की जरूरत है CollisionSystemऔर DamageSystem(हम शायद पहले से ही ये हैं)। इसके CollisionSystemसाथ संवाद करने की आवश्यकताएं DamageSystem: हर बार दो चीजें CollisionSystemएक संदेश को भेजती हैं DamageSystemताकि यह स्वास्थ्य को घटा सके। नुकसान पॉवरअप से भी प्रभावित होता है इसलिए हमें इसे कहीं स्टोर करने की आवश्यकता है। क्या हम एक नया बनाते हैं PowerupComponentजिसे हम संस्थाओं से जोड़ते हैं? लेकिन फिर दDamageSystemइसके बारे में कुछ जानने की जरूरत है, इसके बारे में कुछ नहीं जानना चाहिए - आखिरकार, ऐसी चीजें भी हैं जो नुकसान का सौदा करती हैं जो पावरअप (जैसे Spike) नहीं उठा सकती हैं । क्या हम इस उत्तर के समान क्षति गणना के लिए भी इसे PowerupSystemसंशोधित करने की अनुमति देते हैं ? लेकिन अब दो सिस्टम एक ही डेटा को एक्सेस करते हैं। जैसा कि हमारा खेल अधिक जटिल हो जाता है, यह एक अमूर्त निर्भरता ग्राफ बन जाएगा, जहां कई प्रणालियों के बीच घटक साझा किए जाते हैं। उस बिंदु पर हम सिर्फ वैश्विक स्थिर चर का उपयोग कर सकते हैं और सभी बॉयलरप्लेट से छुटकारा पा सकते हैं।StatComponent

क्या इसे हल करने का कोई प्रभावी तरीका है? एक विचार मुझे घटकों को कुछ कार्य करने देना था, उदाहरण के लिए, StatComponent attack()जो डिफ़ॉल्ट रूप से पूर्णांक देता है, लेकिन जब एक पावरअप हो सकता है:

attack = getAttack compose powerupBy(20) compose powerdownBy(40)

यह उस समस्या को हल नहीं करता attackहै जिसे कई प्रणालियों द्वारा एक्सेस किए गए घटक में सहेजा जाना चाहिए, लेकिन कम से कम मैं फ़ंक्शन ठीक से टाइप कर सकता हूं अगर मेरे पास एक भाषा है जो इसे पर्याप्त रूप से समर्थन करती है:

// In StatComponent
type Strength = PrePowerup | PostPowerup
type Damage = Int
type PrePowerup = Int
type PostPowerup = Int
attack: Strength = getAttack //default value, can be changed by systems
getAttack: PrePowerup

// these functions can be defined in other components or in PowerupSystems
powerupBy: Strength -> PostPowerup
powerdownBy: Strength -> PostPowerup
subtractArmor: Strength -> Damage

// in DamageSystem
dealDamage: Damage -> () = attack compose subtractArmor compose hurtSomeEntity

इस तरह मैं कम से कम सिस्टम द्वारा जोड़े गए विभिन्न कार्यों के सही क्रम की गारंटी देता हूं। किसी भी तरह से, ऐसा लगता है कि मैं तेजी से कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग के लिए यहां आ रहा हूं इसलिए मैं खुद से पूछता हूं कि क्या मुझे शुरू से ही इसका इस्तेमाल नहीं करना चाहिए था (मैंने केवल एफआरपी में देखा है, इसलिए मैं यहां गलत हो सकता हूं)। मैं देखता हूं कि ईसीएस जटिल वर्ग पदानुक्रमों में सुधार है, लेकिन मैं आश्वस्त नहीं हूं कि यह आदर्श है।

क्या इसके आसपास कोई हल है? क्या ECS को अधिक साफ-सुथरा बनाने के लिए एक कार्यक्षमता / पैटर्न मुझे याद आ रहा है? क्या इस समस्या के लिए एफआरपी केवल कड़ाई से बेहतर है? क्या ये समस्याएँ जो मैं कार्यक्रम करने की कोशिश कर रहा हूँ, उसमें निहित जटिलता से उत्पन्न हो रही है; यानी एफआरपी के समान मुद्दे होंगे?



मुझे वास्तव में एरिक का ब्लॉग याद आता है (जब से यह C # के बारे में था)।
ओल्डफ़ार्ट

जवाबों:


21

ईसीएस डेटा छिपाने को पूरी तरह से बर्बाद कर देता है। यह पैटर्न का ट्रेड-ऑफ है।

ईसीएस डिकॉउलिंग में उत्कृष्ट है । एक अच्छा ईसीएस एक चाल प्रणाली को यह घोषणा करने देता है कि यह किसी भी इकाई पर काम करता है जिसमें एक वेग और एक स्थिति घटक है, इस बात की परवाह किए बिना कि किस प्रकार के अस्तित्व मौजूद हैं, या कौन से अन्य सिस्टम इन घटकों का उपयोग करते हैं। यह गेम ऑब्जेक्ट्स को कुछ इंटरफेस को लागू करने की शक्ति को कम करने में कम से कम बराबर है।

समान घटकों को एक्सेस करने वाली दो प्रणालियाँ एक विशेषता है, समस्या नहीं। यह पूरी तरह से अपेक्षित है, और यह किसी भी तरह से सिस्टम को युगल नहीं करता है। यह सच है कि सिस्टम में एक अंतर्निहित निर्भरता ग्राफ होगा, लेकिन वे निर्भरता मॉडल दुनिया में अंतर्निहित हैं। यह कहने के लिए कि क्षति प्रणाली में पावरअप सिस्टम पर निहित निर्भरता नहीं होनी चाहिए, यह दावा करना है कि पावरअप क्षति को प्रभावित नहीं करता है, और यह संभवतः गलत है। हालाँकि, जब निर्भरता मौजूद होती है, तो सिस्टम युग्मित नहीं होते हैं - आप क्षति प्रणाली को प्रभावित किए बिना गेम से पावरअप सिस्टम को हटा सकते हैं, क्योंकि संचार स्टेट घटक के माध्यम से हुआ था और पूरी तरह से निहित था।

इन निर्भरताओं और ऑर्डरिंग सिस्टम को हल करना एक केंद्रीय स्थान में किया जा सकता है, जो कि डीआई सिस्टम में निर्भरता के समाधान के समान है। हां, एक जटिल गेम में सिस्टम का एक जटिल ग्राफ होगा, लेकिन यह जटिलता अंतर्निहित है, और कम से कम यह निहित है।


7

इस तथ्य के आसपास लगभग कोई रास्ता नहीं है कि एक प्रणाली को कई घटकों तक पहुंचने की आवश्यकता है। काम करने के लिए वेलोसिटी सिस्टम जैसी किसी चीज़ के लिए, शायद इसे वेलोसिटीकंपोनेंट एंड पॉजिशनकंपोनेंट तक पहुँच की आवश्यकता होगी। इस बीच RenderingSystem को भी इस डेटा तक पहुंचने की आवश्यकता है। कोई फर्क नहीं पड़ता कि आप क्या करते हैं, कुछ बिंदु पर रेंडरिंग सिस्टम को यह जानना होगा कि ऑब्जेक्ट को कहां प्रस्तुत करना है और वेलोसिटी सिस्टम को यह जानना होगा कि ऑब्जेक्ट को कहां स्थानांतरित करना है।

क्या आप इस के लिए आवश्यकता होती है मुखरता निर्भरता की। प्रत्येक प्रणाली को यह स्पष्ट करना होगा कि वह किस डेटा को पढ़ेगी और वह किस डेटा को लिखेगी। जब कोई सिस्टम किसी विशेष घटक को लाना चाहता है, तो उसे केवल यह स्पष्ट रूप से करने में सक्षम होना चाहिए । अपने सरलतम रूप में, इसमें बस प्रत्येक प्रकार के घटकों की आवश्यकता होती है (जैसे कि RenderSystem को अपने तर्क के रूप में रेंडरकॉमर्स और पॉजिशनकंपर्स की आवश्यकता होती है) और जो कुछ भी उसने बदला है उसे लौटाता है (उदाहरण के लिए केवल रेंडरकॉमर्स)।

इस तरह मैं कम से कम सिस्टम द्वारा जोड़े गए विभिन्न कार्यों के सही क्रम की गारंटी देता हूं

आप इस तरह के डिजाइन में ऑर्डर कर सकते हैं। कुछ भी नहीं कह रहा है कि ईसीएस के लिए आपके सिस्टम को ऑर्डर या ऐसी किसी भी चीज से स्वतंत्र होना चाहिए।

क्या इस समस्या के लिए एफआरपी केवल कड़ाई से बेहतर है? क्या ये समस्याएँ जो मैं कार्यक्रम करने की कोशिश कर रहा हूँ, उसमें निहित जटिलता से उत्पन्न हो रही है; यानी एफआरपी के समान मुद्दे होंगे?

इस इकाई-घटक-सिस्टम डिज़ाइन और FRP का उपयोग करना पारस्परिक रूप से अनन्य नहीं है। वास्तव में, सिस्टम को किसी भी राज्य के रूप में और कुछ नहीं देखा जा सकता है, बस डेटा ट्रांसफ़ॉर्मेशन (घटकों) का प्रदर्शन किया जाता है।

एफआरपी आपको कुछ ऑपरेशन करने के लिए आवश्यक जानकारी का उपयोग करने की समस्या को हल नहीं करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.