जब वे रुकते हैं तो मैं स्थानीय इनपुट भविष्यवाणी के कारण खिलाड़ी को बहने से कैसे रोक सकता हूं?


14

मैं एक 2D सर्वर-क्लाइंट मल्टीप्लेयर गेम इंजन पर काम कर रहा हूं (जिसे आप यहां आज़मा सकते हैं )। यह WebRTC DataChannels का उपयोग करता है । (कनेक्शन पीयर-टू-पीयर हैं, लेकिन होस्ट पीयर अभी भी सर्वर के रूप में कार्य करता है।)

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

यदि नुकसान या पीडीवी है, तो विचलन बड़ा हो सकता है। मुझे लगता है कि ऐसा इसलिए है क्योंकि यदि पहला पैकेट इनपुट में बदलाव का संकेत देता है, तो देरी हो जाती है या गिर जाती है, मेजबान को बाद में पता चलता है, और बाद में उस खिलाड़ी को अपने स्थानीय इनपुट पेडिकिटोन शो से बदलना शुरू कर देता है।

यदि खिलाड़ी आगे बढ़ रहा है, तो हम लागू सुधार की मात्रा को क्रैंक करते हैं, क्योंकि यह कम ध्यान देने योग्य है। यह शुरू होने पर और चलते समय अंतराल को कवर करने के लिए लगता है। हालांकि, किसी भी सुधार में अधिक ध्यान देने योग्य है यदि वे अचानक रोकते हैं। फिर अगर PDV या नुकसान का मतलब है कि मेजबान को लगता है कि वे बाद में रुक गए हैं, तो मेजबान ओवरशूट डेटा को यह कहते हुए वापस भेज देता है कि वे थोड़ा आगे हैं, और सुधार खिलाड़ी को थोड़ा बहाव देता है। परतदार कनेक्शन पर, खिलाड़ी अक्सर एक स्टॉप पर आने के बाद ध्यान से बहाव करते हैं।

मैंने अन्य खेलों में इस पर ध्यान नहीं दिया है। इसे कैसे कम किया जा सकता है?


3
एक पी 2 पी गेम जिसमें एक सर्वर है? यहाँ कुछ गड़बड़ है।
एपीआई-बीस्ट

ओह, 'सर्वर' से मेरा मतलब है 'होस्ट पीयर'।
AshleysBrain

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

आह ... यह वास्तव में एक अच्छा बिंदु है ... मैं मिश्रित हो गया: कनेक्शन सहकर्मी से सहकर्मी हैं (जो कि WebRTC करता है), लेकिन इंजन स्वयं सर्वर-क्लाइंट है (साथियों में से सिर्फ एक सर्वर है )। अच्छी बात।
AshleysBrain

2
क्या यह बनाता है मुझे के बारे में सोच है हमारे बहुत ही एंड्रयू रसेल की छड़ी निन्जा देव यूट्यूब पर लॉग , विशेष रूप से भविष्यवाणी त्रुटियों को ठीक करने पर इस एक । बहती आप का वर्णन उस वीडियो में क्या हो रहा है के समान लगता है और एंड्रयू विवरण बताता है। क्या ये संबंधित हैं, या शायद एक ही मुद्दा?
एको

जवाबों:


8

नेटवर्क लेयर के लिए एक सहमत घड़ी की आवश्यकता है। वे खेल के प्रारंभ में एक घड़ी के मूल्य पर सहमत हो सकते हैं (और बहाव के मामले में समय-समय पर इसे फिर से सिंक करें) ताकि मेजबान जानता है कि किसी विशेष पैकेट को वास्तव में आने में कितना समय लगा और जब ग्राहक ने कार्रवाई की, और इसके विपरीत।

खेल में घड़ियों को सिंक्रनाइज़ करने के एक संभव तरीके के लिए इस लेख को देखें । और भी हैं। विशिष्ट साधन कोई फर्क नहीं पड़ता।

समस्या का दूसरा हिस्सा यह है कि सर्वर उस समय इनपुट लागू कर रहा है जब क्लाइंट ने इनपुट लगाना बंद कर दिया था। इसके लिए सर्वर पर पिछले आंदोलनों की एक बफर की आवश्यकता होती है और अंतिम ज्ञात आंदोलन के पिछले सर्वर से आंदोलन की जानकारी को अनदेखा करने के लिए क्लाइंट पर कुछ तर्क।

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

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

सर्वर को इनपुट घड़ियों को मान्य करने और यह सुनिश्चित करने की आवश्यकता है कि धोखा देने से रोकने के लिए वे उम्मीदों से बहुत अधिक नहीं डूब रहे हैं। इनपुट घड़ी उस अर्ध-गोल-यात्रा समय से बहुत बड़ी नहीं होनी चाहिए, जिसकी आप गणना कर रहे होंगे। ऐसे किसी भी क्लैंप को रखें जो एक उचित सीमा ( [Now-2*RTT,Now]उदाहरण के लिए) हो।

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


1

मैंने स्थिति सुधार के लिए बटन राज्य परिवर्तन और अविश्वसनीय यूडीपी संदेशों को इंगित करने के लिए विश्वसनीय यूडीपी संदेशों का उपयोग किया है। मूल रूप से, निम्नलिखित लेखों ने मेरी बहुत मदद की: https://developer.valvesoftware.com/wiki/Source_Multan_Networking

यह बताता है कि स्थिति सुधार संदेशों के अनुसार लगभग 20 या 30 राज्य की बचत के लिए निरंतर समय अंतराल में खिलाड़ी राज्यों को संचय करने से आंदोलन की भविष्यवाणी। तो ऐसा लगता है कि आपके दूरस्थ खिलाड़ी लगातार प्रीडिक्शन तकनीक लागू करने के बाद भी "अतीत" की वास्तविक स्थिति में नहीं रहेंगे :) नेट संदेश विलंबता के आधार पर आप उस समय अपनी वस्तु स्थिति लगभग प्राप्त कर सकते हैं जब संदेश सिर्फ होस्ट से भेजा गया था।

वर्तमान "ऑन-स्क्रीन" स्थिति को फिर से लिपप (रैखिक प्रक्षेप) गणित का उपयोग करके अनुमानित स्थिति में आसानी से अनुवादित किया जा सकता है। विचार सुधार पैकेज के बीच समय अंतराल में मूल्यों को प्रक्षेपित करना है। तो ऐसा लगता है कि प्रदर्शित वस्तु हमेशा किसी अनुमानित स्थिति की ओर बढ़ रही है। प्रक्षेप मूल्य के लिए मैं 1 को "मध्यम संदेश विलंबता" से विभाजित करके "मध्यम फ्रेम रेंडरिंग टाइम" द्वारा ले जाता हूं ताकि आंदोलन सुचारू दिखाई दे।

इस परिदृश्य में खेल सभी क्लाइंट और सर्वर पर गणना करता है और समय-समय पर वेग और स्थिति जैसे मूल्यों को सही करता है।

एक और बात जो इस मामले में बहुत मदद करती है: अपने गेम लॉजिक को ऑप्टिमाइज़ करें ताकि आप आसानी से यह सुनिश्चित कर सकें कि सर्वर और क्लाइंट इनपुट के आधार पर समान व्यवहार के पास क्लाइंट और क्लाइंट अनुकरण कर सकें।

मैंने पूरी योजना का वर्णन किया है जो मैंने अपने प्रोजेक्ट में उपयोग किया है इसलिए मुझे आशा है कि आपको अपने प्रश्न का उत्तर मिल जाएगा।

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