क्वेक 3 जैसे सटीक नेटवर्क गेम के लिए सर्वर-क्लाइंट घड़ियों को सिंक में कैसे रखें?


15

मैं एक 2 डी टॉप-डाउन-शूटर पर काम कर रहा हूं और क्वेक 3 जैसे नेटवर्क वाले गेम में उपयोग किए जाने वाले अवधारणाओं की प्रतिलिपि बनाने के लिए अपनी पूरी कोशिश कर रहा हूं।

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

मुझे जो समस्या आ रही है वह है "क्लॉक सिंक्रोनाइज़ेशन"।

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

जब भी एक स्नैपशॉट प्राप्त होता है, मैं सर्वर और क्लाइंट घड़ी के बीच अंतर की गणना करके इसे दूर करने में कामयाब रहता हूं।

// For simplicity, don't worry about latency for now...
client_server_clock_delta = snapshot.server_timestamp - client_timestamp;

यह निर्धारित करते समय कि इकाई कितनी दूरी पर है, मैं केवल ग्राहक के वर्तमान समय में अंतर जोड़ता हूं। हालांकि, इसके साथ समस्या यह है कि यह झटके का कारण बनेगा क्योंकि स्नैपशॉट्स के दूसरों की तुलना में तेज / धीमी गति से आने के कारण दो घड़ियों के बीच का अंतर अचानक कम हो जाएगा।

मैं घड़ियों को कितनी बारीकी से सिंक्रनाइज़ कर सकता हूं कि एकमात्र विचारनीय देरी वह है जो प्रक्षेप के लिए कठिन-कोडित है, और जो सामान्य नेटवर्क विलंबता के कारण होता है?

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

संपादित करें: विकिपीडिया के अनुसार , एनटीपी का उपयोग कुछ मिलीसेकंड के भीतर इंटरनेट पर घड़ियों को सिंक्रनाइज़ करने के लिए किया जा सकता है। हालांकि, प्रोटोकॉल जटिल लगता है, और शायद गेम में उपयोग के लिए ओवरकिल?


यह कैसे जटिल है ? यह प्रसारण और आगमन के टाइमस्टैम्प्स के साथ एक अनुरोध और प्रतिक्रिया है, फिर डेल्टा प्राप्त करने के लिए गणित का एक सा है
शाफ़्ट सनकी

@ratchetfreak: ( Mine-control.com/zack/timesync/timesync.html ) के अनुसार , "दुर्भाग्य से, NTP बहुत जटिल है और, अधिक महत्वपूर्ण बात, सही समय डेल्टा पर अभिसरण करने के लिए धीमा। यह NTP नेटवर्क के लिए आदर्श से कम बनाता है। खेल खेलते हैं, जहां खिलाड़ी को तुरंत शुरू करने के लिए एक खेल की उम्मीद है ... "
जॉनकॉम

जवाबों:


10

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

मुझे यहाँ एक विधि मिली , जो अपेक्षाकृत सरल लगती है:

यह एक दूसरे के 150ms (या बेहतर) के भीतर घड़ियों को सिंक्रनाइज़ करने का दावा करता है।

मुझे नहीं पता कि क्या यह मेरे उद्देश्यों के लिए पर्याप्त होगा, लेकिन मैं एक अधिक सटीक विकल्प नहीं खोज पाया।

यहाँ यह एल्गोरिथ्म प्रदान करता है:

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

इन गुणों के साथ एक सरल एल्गोरिथ्म इस प्रकार है:

  1. ग्राहक "टाइम रिक्वेस्ट" पैकेट पर वर्तमान स्थानीय समय का टिकट लगाता है और सर्वर को भेजता है
  2. सर्वर द्वारा रिसीव करने पर, सर्वर स्टैम्प सर्वर-टाइम और रिटर्न करता है
  3. ग्राहक द्वारा प्राप्त होने पर, ग्राहक भेजे गए समय से वर्तमान समय को घटाता है और विलंबता की गणना करने के लिए दो से विभाजित करता है। यह क्लाइंट-सर्वर टाइम डेल्टा निर्धारित करने के लिए सर्वर समय से वर्तमान समय को घटाता है और सही घड़ी डेल्टा प्राप्त करने के लिए अर्ध-विलंबता में जोड़ता है। (अब तक यह अल्गोथिम एसएनटीपी के समान है)
  4. पहले परिणाम को तुरंत घड़ी को अपडेट करने के लिए इस्तेमाल किया जाना चाहिए क्योंकि यह स्थानीय घड़ी को कम से कम सही बॉलपार्क (कम से कम सही टाइमज़ोन!) में मिलेगा।
  5. क्लाइंट हर बार कुछ सेकंड रोकते हुए, स्टेप्स को 3 पांच या अधिक बार 1 से दोहराता है। अंतरिम में अन्य यातायात की अनुमति दी जा सकती है, लेकिन सर्वोत्तम परिणामों के लिए न्यूनतम किया जाना चाहिए
  6. पैकेट प्राप्तियों के परिणाम उच्चतम-विलंबता क्रम में निम्नतम-विलंबता में संचित और क्रमबद्ध होते हैं। माध्यीय विलंबता इस आदेशित सूची से मध्य-बिंदु नमूना चुनकर निर्धारित की जाती है।
  7. माध्यिका से लगभग 1 मानक-विचलन से ऊपर के सभी नमूनों को छोड़ दिया जाता है और शेष नमूनों को एक अंकगणितीय माध्य का उपयोग करके औसत किया जाता है।

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

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


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

@dynamokaj काफी अच्छी तरह से काम करता है।
जोनकॉम

ठंडा। क्या यह संभव है कि आप कार्यान्वयन को साझा कर सकते हैं?
गत्यात्मक

@dynamokaj लगता है कि मैं अभी किसी भी परियोजना में ऐसा कार्यान्वयन नहीं पा सकता हूं जो मैं सोच सकता हूं। वैकल्पिक रूप से जो मेरे लिए पर्याप्त रूप से काम करता है वह है: 1) भविष्य के लिए आप तुरंत उस विलंबता का उपयोग करें जिसकी गणना आप एक पिंग अनुरोध / प्रतिक्रिया से करते हैं और फिर, 2) भविष्य के लिए ऐसी सभी प्रतिक्रियाएं नए मूल्य की ओर धीरे-धीरे, तुरंत नहीं। इसका "औसत" प्रभाव है जो मेरे उद्देश्यों के लिए बहुत सटीक रहा है।
जोनकॉम

कोई दिक्कत नहीं है। मैं Google ऐप इंजन पर अपनी बैकएंड सेवा चला रहा हूं, इसलिए Google के एनटीपी सर्वर का उपयोग करते हुए सर्वर जहां सिंक्रनाइज़ किए जाते हैं: time.google.com ( Developers.google.com/time ) इसलिए मैं अपने Xamarin मोबाइल क्लाइंट के लिए निम्न NTP क्लाइंट का उपयोग करता हूं क्लाइंट और सर्वर के बीच ऑफसेट प्राप्त करने के लिए। Components.xamarin.com/view/rebex-time - जवाब देने के लिए समय निकालने के लिए धन्यवाद।
गत्यात्मक

1

मूल रूप से, आप [संपूर्ण] दुनिया को ठीक नहीं कर सकते हैं और अंततः, आपको रेखा खींचनी होगी।

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

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

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

"यदि आपके पास क्रमी इंटरनेट है, तो आप इस खेल को प्रतिस्पर्धी रूप से नहीं खेल सकते हैं।"
यह बक-बक या बग नहीं है।

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