मैं पूर्ण-राज्य अपडेट की तुलना में मल्टीप्लेयर गेम स्टेट को अधिक कुशलता से कैसे सिंक करूं?


10

मैंने पहले थोड़ा गेम नेटवर्क कोडिंग किया है, लेकिन मुख्य रूप से वास्तविक समय की जरूरतों के बिना टीसीपी के साथ। मैं नेटवर्क आधारित मल्टीप्लेयर के साथ 2 डी जावा गेम पर काम कर रहा हूं। सीखने के लिए, मैं मौजूदा नेटवर्क एपीआई के बिना, यह खुद करना चाहता हूं।

मैं एक सर्वर से क्लाइंट को भेजे गए गेम स्टेट का कुशलता से प्रतिनिधित्व कैसे करूं? सबसे स्पष्ट लेकिन संभवत: कम से कम कुशल तरीका है, जो प्रत्येक खिलाड़ी के स्थान, एनीमेशन राज्य, आदि के साथ कुछ प्रकार के खेल राज्य संदर्भ ऑब्जेक्ट बनाने के लिए होगा, और प्रत्येक अपडेट के लिए प्रत्येक खिलाड़ी को भेज देगा । यह लागू करने के लिए बहुत मुश्किल नहीं लगता है, लेकिन संभवतः वास्तविक-समय की बातचीत के करीब कुछ भी हासिल करने के लिए बहुत बड़ा होगा (निश्चित रूप से इसके साथ मेरा अनुभव सीमित है इसलिए मैं गलत हो सकता हूं)।

क्या आप में से किसी ने भी राज्य में केवल बदलावों को प्रसारित करने के लिए उपयोग किया है, और क्या प्रदर्शन में इतनी बड़ी असमानता है कि यह अतिरिक्त काम के लायक है?


2
पूर्ण फ्रेम हर स्थिति का प्रयास करें और यदि यह बहुत धीमा है (कुछ हद तक सरल 2d गेम के लिए, यह संभवतः पर्याप्त कुशल है) तो अनुकूलन का प्रयास करें। यदि यह ठीक काम करता है, तो यह ठीक काम करता है और आपको इसे तब तक बदलना नहीं पड़ता है जब तक आप अपने नेटवर्किंग को बाद में एक अड़चन नहीं मानते।
रॉबर्ट रूहानी

जवाबों:


10

पूर्ण खेल राज्य को नियमित रूप से प्रसारित करना आमतौर पर संभव नहीं है, हालांकि यह आपके खेल की जटिलता पर बहुत अधिक निर्भर करता है। एक छोटे से विश्व मॉडल के साथ एक सरल खेल के लिए यह काम कर सकता है।

मुझे निम्नलिखित मॉडल के साथ व्यक्तिगत रूप से बहुत अधिक सफलता मिली है:

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

इसने मुझे काफी बड़े खेल जगत के साथ अच्छा प्रदर्शन प्रदान किया है।

एक और टिप, क्लाइंट को सर्वर के संदर्भ के बिना एनीमेशन, कण प्रभाव आदि का ध्यान रखना चाहिए। इनको प्रसारित करने का कोई मतलब नहीं है - उन्हें उचित गेम ईवेंट द्वारा "ट्रिगर" होने की आवश्यकता है।


6

तुल्यकालन आमतौर पर दो भागों में विभाजित होता है: वृद्धिशील और निरपेक्ष।

कभी-कभी आपको सब कुछ संचारित करना चाहिए, यह बड़ा है, लेकिन अगर आप इसे सही तरीके से पैक करते हैं तो आप हर कुछ सेकंड में एक बार ऐसा कर सकते हैं। जगह में सदाबहार लगाने के लिए अच्छा है, वृद्धिशील ताज़ा के दोषों को ठीक करना।

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

बेशक आप केवल सामान अपडेट करते हैं, जब वे क्लाइंट को प्रभावित कर सकते हैं! स्क्रीन से दूर कुछ भी इसके लायक नहीं है। कुछ मानों को कम बार अद्यतन किया जा सकता है। उदाहरण के लिए स्थिति अधिक या कम सटीक होना महत्वपूर्ण है, घटनाओं (मृत्यु, गोली चलाई, विस्फोट, आदि) को तुरंत भेजा जाना चाहिए, जबकि सीधे महत्वपूर्ण मूल्यों में कम ताज़ा अवधि नहीं हो सकती है, उदाहरण के लिए स्कोरबोर्ड, चैट।

डेटा की पैकिंग भी महत्वपूर्ण है। आप एक यूडीपी पैकेज में लगभग 1400 बाइट्स (कॉन्फ़िगरेशन निर्भर, यह डिफ़ॉल्ट है) प्रसारित कर सकते हैं, आमतौर पर हेडर के कुछ बाइट्स होते हैं। तो आप एक पैकेज में 50-100 यूनिट पदों को आसानी से अपडेट कर सकते हैं।


इस सलाह के लिए धन्यवाद Matzi। मैं अभी भी सर्वर और क्लाइंट को लागू करने पर काम कर रहा हूं, लेकिन मैं कुछ दिनों में वापस जांच करूंगा और शायद आपका जवाब स्वीकार कर लूं।
हज

आप सौभाग्यशाली हों! ;)
मत्ती

1

अपने खेल के आधार पर, आप "सिंक्रनाइज़ निष्पादन" मॉडल पर विचार कर सकते हैं, जहां प्रत्येक ग्राहक कीबोर्ड / जॉयस्टिक इनपुट और टाइमर घटनाओं जैसे गैर-नियतात्मक आदानों को साझा करके एक ही खेल खेलने के लिए होता है। (एक मॉडल की तुलना में जहां प्रत्येक ग्राहक स्थानीय सिमुलेशन चलाता है और दूरस्थ सिमुलेशन से परिणाम एकीकृत करने की अपेक्षा करता है)। आपके गेम इंजन को काम करने के लिए आम तौर पर पूरी तरह से निर्धारक होना चाहिए, जो खेल के आधार पर भारी बोझ हो सकता है। लेकिन अगर खेल पहले से ही निर्धारक है, तो यह एक आसान तरीका हो सकता है।

यह #AltDevBlogADay पोस्ट इस दृष्टिकोण के कुछ पहलुओं को एक आधुनिक RTS में शामिल करता है (विशेषकर यह पता लगाने के लिए कि आपके ग्राहक कब "अलग-अलग" गेम चलाना शुरू करते हैं।)

याद रखें कि इसे तब तक सरल रखें जब तक कि यह सिद्ध न हो जाए। :)


1
ये फैक्टरियो के देव से अच्छे पढ़े जाते हैं जो इस दृष्टिकोण का उपयोग करते हैं, और इस दृष्टिकोण की जटिलता पर संकेत देते हैं, लेकिन यह भी दिखाते हैं कि यह व्यवहार्य है: factorio.com/blog/post/fff-76 factorio.com/blog/post-fff -147 फैक्टियो.com
blog/
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.