ฉันจะหยุดผู้เล่นจากการดริฟท์เนื่องจากการคาดการณ์อินพุตภายในเมื่อพวกเขาหยุดได้อย่างไร


14

ฉันกำลังทำงานกับเอ็นจิ้นเกมมัลติเพลเยอร์เซิร์ฟเวอร์ 2D (ซึ่งคุณสามารถลองได้ที่นี่ ) มันใช้ WebRTC DataChannels (การเชื่อมต่อแบบเพียร์ทูเพียร์ แต่โฮสต์เพียร์ยังคงทำหน้าที่เป็นเซิร์ฟเวอร์)

ปัญหาที่ใหญ่ที่สุด (นอกเหนือจากการเชื่อมต่อ) คือการคาดการณ์อินพุตในเครื่อง เราทำตามปกติ: เมื่อกดปุ่มผู้เล่นจะย้ายทันทีบอกโฮสต์ว่ากดคีย์ใดรับข้อมูลกลับจากโฮสต์และเปรียบเทียบกับตำแหน่งทางประวัติศาสตร์ ตำแหน่งได้รับการแก้ไขเมื่อเวลาผ่านไปหากมีความแตกต่าง วิธีนี้ใช้ได้ดีกับการสูญเสียแพ็กเก็ตต่ำหรือPDVแม้ว่า ping จะสูง

หากมีการสูญเสียหรือ PDV ส่วนเบี่ยงเบนอาจมีขนาดใหญ่กว่า ฉันคิดว่าเป็นเพราะถ้าแพ็กเก็ตแรกที่ระบุว่าการเปลี่ยนแปลงของอินพุทล่าช้าหรือหลุดโฮสต์จะค้นพบในภายหลังและเริ่มเปลี่ยนผู้เล่นนั้นช้ากว่าเพรดิตันของพวกเขาในพื้นที่

หากผู้เล่นเคลื่อนไหวเราจะเพิ่มจำนวนการแก้ไขที่นำไปใช้เนื่องจากมันเป็นสิ่งที่น่าสังเกตน้อยกว่า สิ่งนี้ดูเหมือนจะปกปิดช่องว่างเมื่อเริ่มเคลื่อนที่และขณะเคลื่อนที่ อย่างไรก็ตามการแก้ไขใด ๆ ที่น่าสังเกตมากขึ้นถ้าพวกเขามาหยุดทันที จากนั้นหาก PDV หรือการสูญเสียหมายความว่าโฮสต์คิดว่าพวกเขาหยุดในเวลาต่อมาโฮสต์ overshoots ส่งข้อมูลกลับบอกว่าพวกเขากำลังไปข้างหน้าเล็กน้อยและการแก้ไขทำให้ผู้เล่นดริฟท์เล็กน้อย ในการเชื่อมต่อที่ไม่สม่ำเสมอผู้เล่นมักจะล่องลอยหลังจากหยุด

ฉันไม่ได้สังเกตเรื่องนี้ในเกมอื่น สิ่งนี้จะบรรเทาลงได้อย่างไร


3
เกม P2P ที่มีเซิร์ฟเวอร์หรือไม่? มีบางอย่างผิดปกติที่นี่
API-Beast

โอ๊ะโอโดย 'เซิร์ฟเวอร์' ฉันหมายถึง 'โฮสต์เพียร์'
AshleysBrain

2
นั่นไม่เหมือนรูปแบบเพียร์ทูเพียร์เช่นกันเพียงเพราะผู้เล่นคนหนึ่งวางตัวเนื่องจากเซิร์ฟเวอร์ไม่ได้ทำให้เพียร์ทูเพียร์ เทคนิคที่คุณใช้นั้นแน่นอนว่าเป็นเทคนิคไคลเอนต์ - เซิร์ฟเวอร์ ใน P2P คุณเชื่อใจลูกค้าทั้งหมดอย่างสมบูรณ์ (เช่นเพื่อนแต่ละคนถามเพื่อนคนอื่นว่าผู้เล่นของพวกเขาอยู่ที่ไหน) หรือคุณไม่ไว้ใจใครเลย (เช่นคุณชะลอการป้อนข้อมูลจนกว่าเพื่อนทั้งหมดจะได้รับ)
API-Beast

อ่า ... นั่นเป็นจุดที่ดีจริง ๆ ... ฉันสับสน: การเชื่อมต่อแบบเพียร์ทูเพียร์ (ซึ่งเป็นสิ่งที่ WebRTC ทำ) แต่เอ็นจิ้นเองคือเซิร์ฟเวอร์ - ไคลเอนต์ (หนึ่งในเพียร์เป็นแค่เซิร์ฟเวอร์ ) จุดดี.
AshleysBrain

2
สิ่งนี้ทำให้ผมคิดว่าเป็นตัวเองมากแอนดรูรัสเซลของเรา 's สติ๊กนินจาบันทึก dev บน YouTubeโดยเฉพาะอย่างยิ่งคนนี้ในการแก้ไขข้อผิดพลาดในการทำนาย การดริฟท์ที่คุณบรรยายฟังดูคล้ายกับสิ่งที่เกิดขึ้นในวิดีโอนั้นและแอนดรูว์บรรยายรายละเอียด สิ่งเหล่านี้เกี่ยวข้องกันหรืออาจเป็นปัญหาเดียวกัน
Anko

คำตอบ:


8

เลเยอร์เครือข่ายจำเป็นต้องมีนาฬิกาที่ตกลงกันไว้ พวกเขาสามารถเห็นด้วยกับค่านาฬิกาในช่วงต้นเกม (และทำการซิงโครไนซ์เป็นระยะในกรณีที่มีการลอย) ดังนั้นโฮสต์จะรู้ว่าแพ็คเก็ตใด ๆ ที่ส่งมาถึงจริงและเมื่อลูกค้าทำการกระทำและในทางกลับกัน

ดู บทความนี้สำหรับวิธีที่เป็นไปได้วิธีหนึ่งในการซิงโครไนซ์นาฬิกาในเกม มีคนอื่น ๆ วิธีการเฉพาะไม่สำคัญ

ในช่วงครึ่งหลังของปัญหาคือเซิร์ฟเวอร์กำลังใช้อินพุตในเวลาที่ไคลเอ็นต์หยุดใช้อินพุต สิ่งนี้ต้องการบัฟเฟอร์ของการเคลื่อนไหวที่ผ่านมาบนเซิร์ฟเวอร์และตรรกะบางอย่างบนไคลเอ็นต์เพื่อละเว้นอินพุตการเคลื่อนไหวจากเซิร์ฟเวอร์ที่ผ่านการเคลื่อนไหวที่ทราบล่าสุด

ก่อนอื่นบัฟเฟอร์เซิร์ฟเวอร์ เซิร์ฟเวอร์ต้องติดตามการประทับเวลาของอินพุตล่าสุดที่ได้รับจากผู้เล่น นอกจากนี้ยังต้องการการเคลื่อนไหวทั้งหมดที่ใช้กับผู้เล่นตรานาฬิกาของการเคลื่อนไหว หากได้รับข้อมูลเข้าการเคลื่อนไหวล่าสุดทั้งหมดจะถูกนำไปใช้กับการประทับเวลาของนาฬิกาที่ใหม่กว่ากว่าแพ็กเก็ตอินพุตจะถูกดร็อปและการเคลื่อนไหวทั้งหมดจะถูกนำมาใช้ใหม่จากแพ็กเก็ตอินพุต ดังนั้นหากเซิร์ฟเวอร์เคลื่อนย้ายผู้เล่นโดยอิงจากอินพุตบางส่วนอินพุตที่อัปเดตจะยกเลิกการย้ายเหล่านั้นและตำแหน่งใหม่ของผู้เล่นจะยึดตามความรู้อินพุตล่าสุดที่เซิร์ฟเวอร์มี

ในฝั่งไคลเอ็นต์ลูกค้ารู้ว่าเมื่อใดที่มันส่งอินพุตไปยังเซิร์ฟเวอร์ครั้งล่าสุด เนื่องจากผู้เล่นแต่ละคนควรอัปเดตเซิร์ฟเวอร์จากการติดแท็กด้วยนาฬิกาของอินพุตล่าสุดที่เซิร์ฟเวอร์รู้ลูกค้าสามารถเพิกเฉยต่อการอัปเดตเซิร์ฟเวอร์ที่มีแท็กอินพุตที่หมดอายุและเพียงแค่ติดกับการทำนายไคลเอนต์ ในที่สุดการอัพเดทเซิร์ฟเวอร์ใหม่จะมาพร้อมกับข้อมูลที่ทันสมัยและลูกค้าสามารถแก้ไขได้

เซิร์ฟเวอร์จำเป็นต้องตรวจสอบนาฬิกาสัญญาณเข้าและตรวจสอบให้แน่ใจว่าไม่ได้เลื่อนไปจากความคาดหวังมากเกินไปเพื่อป้องกันการโกง นาฬิกาอินพุตไม่ควรมีขนาดใหญ่กว่าเวลาครึ่งทางไป - กลับอย่างมากที่คุณควรคำนวณ ยึดใด ๆ ที่อยู่ในช่วงที่เหมาะสม ( [Now-2*RTT,Now]เช่น)

ลูกค้าจะเห็นอวตารของอวตารของผู้เล่นคนอื่นจำนวนมากหากเวลาแฝงอยู่ในระดับสูงเนื่องจากพวกเขาจะได้รับการอัปเดตจากเซิร์ฟเวอร์ตามการป้อนข้อมูลเก่า แต่ไม่มีวิธีที่จะรู้ว่ามันค้างแล้วจากนั้นเซิร์ฟเวอร์อาจเริ่มส่งตำแหน่งที่แตกต่างกัน อินพุตที่อัปเดตที่ได้รับ (และส่วนหนึ่งของประวัติลดลงและเล่นซ้ำด้วยอินพุตใหม่) ปัญหาล่าสุดนี้กับผู้เล่นคนอื่น ๆ ที่เห็นอวตารอวตารของคุณไม่สามารถแก้ไขได้จริงๆ ความหน่วงแฝงและผู้เล่นที่ติดอยู่ในการเชื่อมต่อที่มีความหน่วงสูงจะเห็นผู้เล่นคนอื่นกระวนกระวายใจมากมายแม้ว่าผู้เล่นของพวกเขาจะเคลื่อนไหวอย่างราบรื่น การแก้ไขเพียงอย่างเดียวคือเล่นบนการเชื่อมต่อที่ดีขึ้นหรือกับเพื่อน / เซิร์ฟเวอร์ที่มีเวลาแฝงน้อยกว่า


1

ฉันใช้ข้อความ UDP ที่เชื่อถือได้เพื่อระบุการเปลี่ยนแปลงสถานะปุ่มและข้อความ UDP ที่ไม่น่าเชื่อถือสำหรับการแก้ไขตำแหน่ง Basicaly บทความต่อไปนี้ช่วยฉันได้มาก: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

มันบอกเกี่ยวกับการทำนายการเคลื่อนไหวโดยการจัดเก็บสถานะผู้เล่นในช่วงเวลาคงที่ตามข้อความการแก้ไขตำแหน่งที่มาถึงการบันทึกประมาณ 20 หรือ 30 รัฐ ดังนั้นดูเหมือนว่าผู้เล่นระยะไกลของคุณจะอาศัยอยู่ใน "อดีต" ที่เกิดขึ้นจริงโดยใช้เทคนิคการทำนายอย่างต่อเนื่อง :) โดยขึ้นอยู่กับเวลาแฝงของข้อความสุทธิคุณจะได้ตำแหน่งวัตถุของคุณในเวลาที่ข้อความเพิ่งถูกส่งจากโฮสต์

ตำแหน่ง "บนหน้าจอ" ในปัจจุบันนั้นสามารถแปลเป็นตำแหน่งที่คาดการณ์ได้อย่างราบรื่นโดยใช้คณิตศาสตร์ Lerp (การประมาณค่าเชิงเส้น) แนวคิดคือการสอดแทรกค่าในช่วงเวลาระหว่างแพ็กเกจการแก้ไข ดังนั้นดูเหมือนว่าวัตถุที่แสดงจะเคลื่อนที่ไปยังตำแหน่งที่คาดการณ์ไว้เสมอ สำหรับค่าการแก้ไขฉันใช้ 1 หารด้วย "เวลาแฝงข้อความปานกลาง" หารด้วย "เวลาในการแสดงเฟรมกลาง" เพื่อให้การเคลื่อนไหวดูราบรื่น

ในสถานการณ์สมมตินี้เกมคำนวณบนไคลเอนต์และเซิร์ฟเวอร์ทั้งหมดเพื่อแก้ไขค่าเช่นความเร็วและตำแหน่งเป็นครั้งคราว

อีกสิ่งหนึ่งที่ช่วยได้มากในกรณีนี้: ปรับตรรกะเกมของคุณเพื่อให้คุณสามารถลบเอฟเฟกต์เวลาแฝงได้อย่างง่ายดายโดยมั่นใจว่าเซิร์ฟเวอร์และไคลเอนต์สามารถเลียนแบบพฤติกรรมที่คล้ายกันโดยอิงตามอินพุตของผู้เล่น

ฉันอธิบายโครงร่างทั้งหมดที่ฉันใช้ในโครงการของฉันดังนั้นฉันหวังว่าคุณจะพบคำตอบสำหรับคำถามของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.