गेम इंजन में कंपोनेंट सिस्टम के आर्किटेक्चर, उनके लाभ, कार्यान्वयन विवरण और उन्नत तकनीकों का अन्वेषण करें। दुनिया भर के गेम डेवलपर्स के लिए एक व्यापक गाइड।
गेम इंजन आर्किटेक्चर: कंपोनेंट सिस्टम का गहन विश्लेषण
गेम डेवलपमेंट के क्षेत्र में, आकर्षक और मनोरंजक अनुभव बनाने के लिए एक अच्छी तरह से संरचित गेम इंजन सर्वोपरि है। गेम इंजन के लिए सबसे प्रभावशाली आर्किटेक्चरल पैटर्न में से एक कंपोनेंट सिस्टम है। यह आर्किटेक्चरल शैली मॉड्यूलरिटी, लचीलेपन और पुन: प्रयोज्यता पर जोर देती है, जिससे डेवलपर्स स्वतंत्र कंपोनेंट्स के संग्रह से जटिल गेम एंटिटी बना सकते हैं। यह लेख दुनिया भर के गेम डेवलपर्स को लक्षित करते हुए कंपोनेंट सिस्टम, उनके लाभों, कार्यान्वयन संबंधी विचारों और उन्नत तकनीकों का एक व्यापक अन्वेषण प्रदान करता है।
कंपोनेंट सिस्टम क्या है?
मूल रूप से, एक कंपोनेंट सिस्टम (अक्सर एक एंटिटी-कंपोनेंट-सिस्टम या ECS आर्किटेक्चर का हिस्सा) एक डिज़ाइन पैटर्न है जो इनहेरिटेंस (inheritance) के बजाय कंपोजीशन (composition) को बढ़ावा देता है। गहरी क्लास पदानुक्रम पर निर्भर रहने के बजाय, गेम ऑब्जेक्ट्स (या एंटिटी) को पुन: प्रयोज्य कंपोनेंट्स के भीतर समाहित डेटा और लॉजिक के लिए कंटेनर के रूप में माना जाता है। प्रत्येक कंपोनेंट एंटिटी के व्यवहार या स्थिति के एक विशिष्ट पहलू का प्रतिनिधित्व करता है, जैसे कि उसकी स्थिति, रूप, भौतिकी गुण, या AI लॉजिक।
एक लेगो सेट के बारे में सोचें। आपके पास अलग-अलग ईंटें (कंपोनेंट्स) होती हैं, जिन्हें अलग-अलग तरीकों से मिलाने पर, वस्तुओं (एंटिटी) की एक विशाल श्रृंखला बनाई जा सकती है – एक कार, एक घर, एक रोबोट, या कुछ भी जिसकी आप कल्पना कर सकते हैं। इसी तरह, एक कंपोनेंट सिस्टम में, आप अपने गेम एंटिटी की विशेषताओं को परिभाषित करने के लिए विभिन्न कंपोनेंट्स को मिलाते हैं।
मुख्य अवधारणाएँ:
- एंटिटी (Entity): दुनिया में एक गेम ऑब्जेक्ट का प्रतिनिधित्व करने वाला एक अद्वितीय पहचानकर्ता। यह अनिवार्य रूप से एक खाली कंटेनर है जिससे कंपोनेंट्स जुड़े होते हैं। एंटिटी में स्वयं कोई डेटा या लॉजिक नहीं होता है।
- कंपोनेंट (Component): एक डेटा संरचना जो एक एंटिटी के बारे में विशिष्ट जानकारी संग्रहीत करती है। उदाहरणों में पोजिशनकंपोनेंट, वेलोसिटीकंपोनेंट, स्प्राइटएकंपोनेंट, हेल्थकंपोनेंट, आदि शामिल हैं। कंपोनेंट्स में *डेटा* होता है, लॉजिक नहीं।
- सिस्टम (System): एक मॉड्यूल जो उन एंटिटी पर काम करता है जिनमें कंपोनेंट्स के विशिष्ट संयोजन होते हैं। सिस्टम में *लॉजिक* होता है और वे एंटिटी के माध्यम से पुनरावृति करते हैं ताकि उनके कंपोनेंट्स के आधार पर क्रियाएं कर सकें। उदाहरण के लिए, एक रेंडरिंगसिस्टम उन सभी एंटिटी के माध्यम से पुनरावृति कर सकता है जिनमें पोजिशनकंपोनेंट और स्प्राइटएकंपोनेंट दोनों हैं, और उनके स्प्राइट्स को निर्दिष्ट स्थानों पर चित्रित कर सकता है।
कंपोनेंट सिस्टम के लाभ
एक कंपोनेंट सिस्टम आर्किटेक्चर को अपनाने से गेम डेवलपमेंट परियोजनाओं के लिए कई फायदे मिलते हैं, खासकर स्केलेबिलिटी, रखरखाव और लचीलेपन के मामले में।1. बढ़ी हुई मॉड्यूलरिटी
कंपोनेंट सिस्टम एक अत्यधिक मॉड्यूलर डिजाइन को बढ़ावा देते हैं। प्रत्येक कंपोनेंट कार्यक्षमता के एक विशिष्ट हिस्से को समाहित करता है, जिससे इसे समझना, संशोधित करना और पुन: उपयोग करना आसान हो जाता है। यह मॉड्यूलरिटी विकास प्रक्रिया को सरल बनाती है और परिवर्तन करते समय अनपेक्षित दुष्प्रभावों को पेश करने के जोखिम को कम करती है।
2. बढ़ा हुआ लचीलापन
पारंपरिक ऑब्जेक्ट-ओरिएंटेड इनहेरिटेंस कठोर क्लास पदानुक्रम को जन्म दे सकती है जिसे बदलती आवश्यकताओं के अनुकूल बनाना मुश्किल होता है। कंपोनेंट सिस्टम काफी अधिक लचीलापन प्रदान करते हैं। आप नई क्लास बनाए बिना या मौजूदा को संशोधित किए बिना उनके व्यवहार को संशोधित करने के लिए एंटिटी से कंपोनेंट्स को आसानी से जोड़ या हटा सकते हैं। यह विविध और गतिशील गेम दुनिया बनाने के लिए विशेष रूप से उपयोगी है।
उदाहरण: कल्पना कीजिए कि एक कैरेक्टर एक साधारण NPC के रूप में शुरू होता है। बाद में गेम में, आप उन्हें खिलाड़ी द्वारा नियंत्रणीय बनाने का निर्णय लेते हैं। एक कंपोनेंट सिस्टम के साथ, आप बेस NPC कोड को बदले बिना, बस एंटिटी में एक `PlayerInputComponent` और एक `MovementComponent` जोड़ सकते हैं।
3. बेहतर पुन: प्रयोज्यता
कंपोनेंट्स को कई एंटिटी में पुन: उपयोग करने योग्य होने के लिए डिज़ाइन किया गया है। एक एकल `SpriteComponent` का उपयोग विभिन्न प्रकार की वस्तुओं को प्रस्तुत करने के लिए किया जा सकता है, पात्रों से लेकर प्रोजेक्टाइल तक पर्यावरण तत्वों तक। यह पुन: प्रयोज्यता कोड दोहराव को कम करती है और विकास प्रक्रिया को सुव्यवस्थित करती है।
उदाहरण: एक `DamageComponent` का उपयोग खिलाड़ी पात्रों और दुश्मन AI दोनों द्वारा किया जा सकता है। क्षति की गणना और प्रभाव लागू करने का लॉजिक वही रहता है, भले ही एंटिटी उस कंपोनेंट का मालिक हो।
4. डेटा-ओरिएंटेड डिज़ाइन (DOD) संगतता
कंपोनेंट सिस्टम स्वाभाविक रूप से डेटा-ओरिएंटेड डिज़ाइन (DOD) सिद्धांतों के लिए अच्छी तरह से अनुकूल हैं। DOD कैश उपयोग को अनुकूलित करने और प्रदर्शन में सुधार करने के लिए मेमोरी में डेटा को व्यवस्थित करने पर जोर देता है। क्योंकि कंपोनेंट्स आमतौर पर केवल डेटा (बिना संबंधित लॉजिक के) संग्रहीत करते हैं, उन्हें आसानी से सन्निहित मेमोरी ब्लॉक में व्यवस्थित किया जा सकता है, जिससे सिस्टम बड़ी संख्या में एंटिटी को कुशलतापूर्वक संसाधित कर सकते हैं।
5. स्केलेबिलिटी और रखरखाव
जैसे-जैसे गेम प्रोजेक्ट्स की जटिलता बढ़ती है, रखरखाव तेजी से महत्वपूर्ण होता जाता है। कंपोनेंट सिस्टम की मॉड्यूलर प्रकृति बड़े कोडबेस को प्रबंधित करना आसान बनाती है। एक कंपोनेंट में किए गए परिवर्तनों से सिस्टम के अन्य हिस्सों को प्रभावित करने की संभावना कम होती है, जिससे बग्स के आने का खतरा कम हो जाता है। चिंताओं का स्पष्ट पृथक्करण भी नई टीम के सदस्यों के लिए प्रोजेक्ट को समझना और उसमें योगदान देना आसान बनाता है।
6. इनहेरिटेंस पर कंपोजीशन
कंपोनेंट सिस्टम "इनहेरिटेंस पर कंपोजीशन" का समर्थन करते हैं, जो एक शक्तिशाली डिजाइन सिद्धांत है। इनहेरिटेंस क्लास के बीच तंग युग्मन बनाता है और "नाजुक बेस क्लास" समस्या को जन्म दे सकता है, जहां एक पेरेंट क्लास में परिवर्तन से उसके बच्चों के लिए अनपेक्षित परिणाम हो सकते हैं। दूसरी ओर, कंपोजीशन आपको छोटे, स्वतंत्र कंपोनेंट्स को मिलाकर जटिल ऑब्जेक्ट बनाने की अनुमति देता है, जिसके परिणामस्वरूप एक अधिक लचीला और मजबूत सिस्टम बनता है।
एक कंपोनेंट सिस्टम लागू करना
एक कंपोनेंट सिस्टम को लागू करने में कई प्रमुख विचार शामिल होते हैं। विशिष्ट कार्यान्वयन विवरण प्रोग्रामिंग भाषा और लक्ष्य प्लेटफॉर्म के आधार पर अलग-अलग होंगे, लेकिन मौलिक सिद्धांत समान रहते हैं।1. एंटिटी प्रबंधन
पहला कदम एंटिटी के प्रबंधन के लिए एक तंत्र बनाना है। आमतौर पर, एंटिटी को अद्वितीय पहचानकर्ताओं, जैसे कि पूर्णांक या GUIDs द्वारा दर्शाया जाता है। एक एंटिटी प्रबंधक एंटिटी को बनाने, नष्ट करने और ट्रैक करने के लिए जिम्मेदार है। प्रबंधक सीधे एंटिटी से संबंधित डेटा या लॉजिक नहीं रखता है; इसके बजाय, यह एंटिटी आईडी का प्रबंधन करता है।
उदाहरण (C++):
class EntityManager {
public:
Entity CreateEntity() {
Entity entity = nextEntityId_++;
return entity;
}
void DestroyEntity(Entity entity) {
// Remove all components associated with the entity
for (auto& componentMap : componentStores_) {
componentMap.second.erase(entity);
}
}
private:
Entity nextEntityId_ = 0;
std::unordered_map> componentStores_;
};
2. कंपोनेंट स्टोरेज
कंपोनेंट्स को इस तरह से संग्रहीत करने की आवश्यकता है जो सिस्टम को किसी दिए गए एंटिटी से जुड़े कंपोनेंट्स तक कुशलतापूर्वक पहुंचने की अनुमति दे। एक सामान्य दृष्टिकोण प्रत्येक कंपोनेंट प्रकार के लिए अलग-अलग डेटा संरचनाओं (अक्सर हैश मैप्स या ऐरे) का उपयोग करना है। प्रत्येक संरचना एंटिटी आईडी को कंपोनेंट इंस्टेंस से मैप करती है।
उदाहरण (वैचारिक):
ComponentStore positions;
ComponentStore velocities;
ComponentStore sprites;
3. सिस्टम डिजाइन
सिस्टम एक कंपोनेंट सिस्टम के वर्कहॉर्स होते हैं। वे एंटिटी को संसाधित करने और उनके कंपोनेंट्स के आधार पर कार्य करने के लिए जिम्मेदार हैं। प्रत्येक सिस्टम आमतौर पर उन एंटिटी पर काम करता है जिनमें कंपोनेंट्स का एक विशिष्ट संयोजन होता है। सिस्टम उन एंटिटी पर पुनरावृति करते हैं जिनमें वे रुचि रखते हैं और आवश्यक गणना या अपडेट करते हैं।
उदाहरण: एक `MovementSystem` उन सभी एंटिटी के माध्यम से पुनरावृति कर सकता है जिनमें `PositionComponent` और `VelocityComponent` दोनों हैं, उनकी स्थिति को उनकी गति और बीते हुए समय के आधार पर अपडेट करता है।
class MovementSystem {
public:
void Update(float deltaTime) {
for (auto& [entity, position] : entityManager_.GetComponentStore()) {
if (entityManager_.HasComponent(entity)) {
VelocityComponent* velocity = entityManager_.GetComponent(entity);
position->x += velocity->x * deltaTime;
position->y += velocity->y * deltaTime;
}
}
}
private:
EntityManager& entityManager_;
};
4. कंपोनेंट पहचान और टाइप सुरक्षा
टाइप सुरक्षा सुनिश्चित करना और कंपोनेंट्स की कुशलतापूर्वक पहचान करना महत्वपूर्ण है। आप कंपाइल-टाइम तकनीकों जैसे टेम्पलेट्स या रनटाइम तकनीकों जैसे टाइप आईडी का उपयोग कर सकते हैं। कंपाइल-टाइम तकनीकें आम तौर पर बेहतर प्रदर्शन प्रदान करती हैं लेकिन कंपाइल समय बढ़ा सकती हैं। रनटाइम तकनीकें अधिक लचीली होती हैं लेकिन रनटाइम ओवरहेड ला सकती हैं।
उदाहरण (C++ टेम्पलेट्स के साथ):
template
class ComponentStore {
public:
void AddComponent(Entity entity, T component) {
components_[entity] = component;
}
T& GetComponent(Entity entity) {
return components_[entity];
}
bool HasComponent(Entity entity) {
return components_.count(entity) > 0;
}
private:
std::unordered_map components_;
};
5. कंपोनेंट निर्भरता को संभालना
कुछ सिस्टम को किसी एंटिटी पर काम करने से पहले विशिष्ट कंपोनेंट्स की उपस्थिति की आवश्यकता हो सकती है। आप सिस्टम के अपडेट लॉजिक के भीतर आवश्यक कंपोनेंट्स की जांच करके या अधिक परिष्कृत निर्भरता प्रबंधन प्रणाली का उपयोग करके इन निर्भरताओं को लागू कर सकते हैं।
उदाहरण: एक `RenderingSystem` को किसी एंटिटी को प्रस्तुत करने से पहले `PositionComponent` और `SpriteComponent` दोनों की उपस्थिति की आवश्यकता हो सकती है। यदि कोई भी कंपोनेंट गायब है, तो सिस्टम एंटिटी को छोड़ देगा।
उन्नत तकनीकें और विचार
बुनियादी कार्यान्वयन से परे, कई उन्नत तकनीकें कंपोनेंट सिस्टम की क्षमताओं और प्रदर्शन को और बढ़ा सकती हैं।1. आर्केटाइप्स
एक आर्केटाइप कंपोनेंट्स का एक अनूठा संयोजन है। एक ही आर्केटाइप वाली एंटिटी एक ही मेमोरी लेआउट साझा करती हैं, जो सिस्टम को उन्हें अधिक कुशलता से संसाधित करने की अनुमति देती है। सभी एंटिटी के माध्यम से पुनरावृति करने के बजाय, सिस्टम उन एंटिटी के माध्यम से पुनरावृति कर सकते हैं जो एक विशिष्ट आर्केटाइप से संबंधित हैं, जिससे प्रदर्शन में काफी सुधार होता है।
2. चंक्ड ऐरे
चंक्ड ऐरे एक ही प्रकार के कंपोनेंट्स को मेमोरी में लगातार संग्रहीत करते हैं, जिन्हें चंक्स में समूहीकृत किया जाता है। यह व्यवस्था कैश उपयोग को अधिकतम करती है और मेमोरी विखंडन को कम करती है। सिस्टम फिर इन चंक्स के माध्यम से कुशलतापूर्वक पुनरावृति कर सकते हैं, एक साथ कई एंटिटी को संसाधित कर सकते हैं।
3. इवेंट सिस्टम
इवेंट सिस्टम कंपोनेंट्स और सिस्टम को प्रत्यक्ष निर्भरता के बिना एक दूसरे के साथ संवाद करने की अनुमति देते हैं। जब कोई घटना होती है (उदाहरण के लिए, एक एंटिटी को क्षति होती है), तो सभी इच्छुक श्रोताओं को एक संदेश प्रसारित किया जाता है। यह डिकूप्लिंग मॉड्यूलरिटी में सुधार करता है और चक्रीय निर्भरता को पेश करने के जोखिम को कम करता है।
4. समानांतर प्रसंस्करण (Parallel Processing)
कंपोनेंट सिस्टम समानांतर प्रसंस्करण के लिए अच्छी तरह से अनुकूल हैं। सिस्टम को समानांतर में निष्पादित किया जा सकता है, जिससे आप मल्टी-कोर प्रोसेसर का लाभ उठा सकते हैं और प्रदर्शन में काफी सुधार कर सकते हैं, खासकर बड़ी संख्या में एंटिटी वाली जटिल गेम दुनिया में। डेटा रेस से बचने और थ्रेड सुरक्षा सुनिश्चित करने के लिए सावधानी बरतनी चाहिए।
5. सीरियलाइज़ेशन और डीसीरियलाइज़ेशन
गेम स्टेट्स को सहेजने और लोड करने के लिए एंटिटी और उनके कंपोनेंट्स को सीरियलाइज़ और डीसीरियलाइज़ करना आवश्यक है। इस प्रक्रिया में एंटिटी डेटा के इन-मेमोरी प्रतिनिधित्व को एक ऐसे प्रारूप में परिवर्तित करना शामिल है जिसे डिस्क पर संग्रहीत किया जा सकता है या नेटवर्क पर प्रेषित किया जा सकता है। कुशल भंडारण और पुनर्प्राप्ति के लिए JSON या बाइनरी सीरियलाइज़ेशन जैसे प्रारूप का उपयोग करने पर विचार करें।
6. परफॉर्मेंस ऑप्टिमाइज़ेशन
हालांकि कंपोनेंट सिस्टम कई लाभ प्रदान करते हैं, प्रदर्शन के प्रति सचेत रहना महत्वपूर्ण है। अत्यधिक कंपोनेंट लुकअप से बचें, कैश उपयोग के लिए डेटा लेआउट को अनुकूलित करें, और मेमोरी आवंटन ओवरहेड को कम करने के लिए ऑब्जेक्ट पूलिंग जैसी तकनीकों का उपयोग करने पर विचार करें। प्रदर्शन की बाधाओं की पहचान करने के लिए अपने कोड की प्रोफाइलिंग महत्वपूर्ण है।
लोकप्रिय गेम इंजन में कंपोनेंट सिस्टम
कई लोकप्रिय गेम इंजन कंपोनेंट-आधारित आर्किटेक्चर का उपयोग करते हैं, या तो मूल रूप से या एक्सटेंशन के माध्यम से। यहां कुछ उदाहरण दिए गए हैं:1. यूनिटी (Unity)
यूनिटी एक व्यापक रूप से इस्तेमाल किया जाने वाला गेम इंजन है जो कंपोनेंट-आधारित आर्किटेक्चर का उपयोग करता है। यूनिटी में गेम ऑब्जेक्ट अनिवार्य रूप से कंपोनेंट्स के लिए कंटेनर होते हैं, जैसे कि `Transform`, `Rigidbody`, `Collider`, और कस्टम स्क्रिप्ट। डेवलपर्स रनटाइम पर गेम ऑब्जेक्ट्स के व्यवहार को संशोधित करने के लिए कंपोनेंट्स जोड़ और हटा सकते हैं। यूनिटी कंपोनेंट्स बनाने और प्रबंधित करने के लिए एक विज़ुअल एडिटर और स्क्रिप्टिंग क्षमताएं दोनों प्रदान करता है।
2. अनरियल इंजन (Unreal Engine)
अनरियल इंजन भी एक कंपोनेंट-आधारित आर्किटेक्चर का समर्थन करता है। अनरियल इंजन में एक्टर्स के साथ कई कंपोनेंट्स जुड़े हो सकते हैं, जैसे कि `StaticMeshComponent`, `MovementComponent`, और `AudioComponent`। अनरियल इंजन का ब्लूप्रिंट विज़ुअल स्क्रिप्टिंग सिस्टम डेवलपर्स को कंपोनेंट्स को एक साथ जोड़कर जटिल व्यवहार बनाने की अनुमति देता है।
3. गोडोट इंजन (Godot Engine)
गोडोट इंजन एक सीन-आधारित प्रणाली का उपयोग करता है जहाँ नोड्स (एंटिटी के समान) के बच्चे (कंपोनेंट्स के समान) हो सकते हैं। हालांकि यह एक शुद्ध ECS नहीं है, यह कंपोजीशन के कई समान लाभों और सिद्धांतों को साझा करता है।
वैश्विक विचार और सर्वोत्तम प्रथाएं
एक वैश्विक दर्शकों के लिए एक कंपोनेंट सिस्टम डिजाइन और कार्यान्वित करते समय, निम्नलिखित सर्वोत्तम प्रथाओं पर विचार करें:- स्थानीयकरण (Localization): टेक्स्ट और अन्य संपत्तियों के स्थानीयकरण का समर्थन करने के लिए कंपोनेंट्स डिज़ाइन करें। उदाहरण के लिए, स्थानीयकृत टेक्स्ट स्ट्रिंग्स को संग्रहीत करने के लिए अलग-अलग कंपोनेंट्स का उपयोग करें।
- अंतर्राष्ट्रीयकरण (Internationalization): कंपोनेंट्स में डेटा संग्रहीत और संसाधित करते समय विभिन्न संख्या प्रारूपों, दिनांक प्रारूपों और कैरेक्टर सेट पर विचार करें। सभी टेक्स्ट के लिए यूनिकोड का उपयोग करें।
- स्केलेबिलिटी (Scalability): अपने कंपोनेंट सिस्टम को बड़ी संख्या में एंटिटी और कंपोनेंट्स को कुशलतापूर्वक संभालने के लिए डिज़ाइन करें, खासकर यदि आपका गेम वैश्विक दर्शकों के लिए लक्षित है।
- पहुंच (Accessibility): स्क्रीन रीडर और वैकल्पिक इनपुट विधियों जैसी पहुंच सुविधाओं का समर्थन करने के लिए कंपोनेंट्स डिज़ाइन करें।
- सांस्कृतिक संवेदनशीलता (Cultural Sensitivity): गेम सामग्री और यांत्रिकी डिजाइन करते समय सांस्कृतिक मतभेदों का ध्यान रखें। रूढ़िवादिता से बचें और सुनिश्चित करें कि आपका गेम वैश्विक दर्शकों के लिए उपयुक्त है।
- स्पष्ट दस्तावेज़ीकरण (Clear Documentation): अपने कंपोनेंट सिस्टम के लिए व्यापक दस्तावेज़ीकरण प्रदान करें, जिसमें प्रत्येक कंपोनेंट और सिस्टम की विस्तृत व्याख्या शामिल हो। इससे विविध पृष्ठभूमि के डेवलपर्स के लिए आपके सिस्टम को समझना और उपयोग करना आसान हो जाएगा।
निष्कर्ष
कंपोनेंट सिस्टम गेम डेवलपमेंट के लिए एक शक्तिशाली और लचीला आर्किटेक्चरल पैटर्न प्रदान करते हैं। मॉड्यूलरिटी, पुन: प्रयोज्यता और कंपोजीशन को अपनाकर, कंपोनेंट सिस्टम डेवलपर्स को जटिल और स्केलेबल गेम दुनिया बनाने में सक्षम बनाते हैं। चाहे आप एक छोटा इंडी गेम बना रहे हों या एक बड़े पैमाने पर AAA शीर्षक, कंपोनेंट सिस्टम को समझना और लागू करना आपकी विकास प्रक्रिया और आपके गेम की गुणवत्ता में काफी सुधार कर सकता है। जैसे ही आप अपनी गेम डेवलपमेंट यात्रा शुरू करते हैं, अपनी परियोजना की विशिष्ट आवश्यकताओं को पूरा करने वाले एक मजबूत और अनुकूलनीय कंपोनेंट सिस्टम को डिजाइन करने के लिए इस गाइड में उल्लिखित सिद्धांतों पर विचार करें, और दुनिया भर के खिलाड़ियों के लिए आकर्षक अनुभव बनाने के लिए विश्व स्तर पर सोचना याद रखें।