บ่อยครั้งในการอัพเดทไคลเอนต์เกมเกี่ยวกับโลก


10

ใช้socket.ioฉันมีการสื่อสารคล้ายกับ MMORPG อื่น ๆ ซึ่งเป็นการเชื่อมต่อที่มั่นคงกับข้อความ

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

เป็นความคิดที่ดีกว่าหรือไม่ที่จะ 'รวบรวม' สิ่งเหล่านี้และออกอากาศพวกเขาพูดครั้งเดียวใน 1/10 ของวินาที?

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

คำตอบ:


16

ฉันจะเข้าใกล้สิ่งนี้จากการสนทนาระดับสูงจากนั้นพยายามหาคำถามของคุณ เพื่อประโยชน์ในการเปิดเผยข้อมูลฉันไม่ได้มีประสบการณ์ส่วนตัวในการใช้ socket.io แต่มีการสัมผัสกับพื้นที่ปัญหามากมายเกี่ยวกับ MMORPG

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

ในฐานะนักพัฒนา MMORPG เราวางแผนเพื่อความสำเร็จที่ยิ่งใหญ่ (หรือที่รู้จักกันในชื่อความสำเร็จอย่างหายนะ) ซึ่งมีจำนวนมากที่เปิดสัญญาณไฟเตือนและไซเรน หนึ่งในจำนวนมากที่น่ากลัวที่อัพอัลกอริธึมคือ N-squared (N ^ 2 ต่อจากนี้) ในคำถามของคุณสิ่งแรกที่กระโดดออกมาหาฉันคือมันฟังดูเหมือนการออกแบบที่เรียกว่าเอนทิตีเพื่อเผยแพร่ข้อมูลไปยัง หน่วยงานที่เชื่อมต่ออื่น ๆ ทั้งหมด นี่คือตัวอย่างคลาสสิกของปัญหา N ^ 2

โดยทั่วไปแล้ว MMOs จะจัดการกับปัญหา N ^ 2 โดยการโจมตีปัญหาด้วยวิธีต่างๆ ระบบการรับรู้ (สถานการณ์เชิงพื้นที่ ฯลฯ ) ที่หน่วยงานตระหนักถึงเซตย่อยบางส่วนของหน่วยงานอื่น ๆ ทั้งหมดการแบ่งผู้เล่นออกเป็น "เศษ" ที่แตกต่างกันการแบ่งผู้เล่นใน "โซน" และ / หรืออินสแตนซ์ ผู้เล่นจากการรวมตัวกัน (พายุเทเลพอร์ตของ Asheron Call) ฯลฯ

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

  • เส้นทางการสื่อสารที่เชื่อถือได้และไม่น่าเชื่อถือ (TCP การใช้งานที่กำหนดเองของแพ็คเก็ต UDP และ UDP ที่เชื่อถือได้)
  • การสร้างแบนด์วิดท์ (การจัดลำดับความสำคัญอายุการใช้งาน ฯลฯ )
  • การจำลองแบบอัตโนมัติของข้อมูลภาคสนาม / viarable และการเรียกใช้ฟังก์ชั่น
  • ชุดข้อมูลอะตอม (เช่นข้อมูลที่สื่อสารด้วยกัน)
  • การอัปเดตแบบไม่ต่อเนื่อง (เช่นที่การเปลี่ยนทุกครั้งสำคัญ)
  • การแก้ไขความล่าช้า
  • เทคนิคที่หลากหลายเพื่อให้ลูกค้ารู้สึกตอบสนอง

ฉันพบว่าเอกสารระบบเครือข่าย Unrealและเอกสารระบบเครือข่ายValveให้ข้อมูลเบื้องต้นที่ดีสำหรับปัญหาที่หลากหลาย

ดังนั้นตอนนี้ให้เข้าใกล้คำถาม

เป็นความคิดที่ดีกว่าหรือไม่ที่จะ 'รวบรวม' สิ่งเหล่านี้และออกอากาศพวกเขาพูดครั้งเดียวใน 1/10 ของวินาที?

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

โดยทั่วไปแล้วไคลเอนต์สำหรับเกม MMORPGs และ FPS นั้นจะได้รับการออกแบบเพื่อให้เห็นภาพสิ่งที่ "ดู" ถูกต้องแม้ว่าพวกเขาจะไม่ได้รับการอัพเดตสำหรับเฟรมอัปเดตมากกว่าที่เป็น "ปกติ" ก็ตาม เมื่อใช้การสื่อสารที่ไม่น่าเชื่อถือ (UDP) คุณสามารถคาดหวังว่าจะสูญเสียการอัปเดตจำนวนหนึ่งไปสู่โมฆะลูกค้าสามารถทำสิ่งนี้ได้โดยส่งการอัปเดตบ่อยกว่าที่ใช้กับการขนส่งที่เชื่อถือได้

จากการตรวจสอบคร่าวๆของเอกสาร socket.io ดูเหมือนว่ามันรองรับเส้นทางการสื่อสารทั้งที่เชื่อถือได้และไม่น่าเชื่อถือ (ระเหยในคำศัพท์)

ฉันจะเข้าหาสิ่งนี้ก่อนโดยการแก้ปัญหาการอัพเดตความถี่ที่จำเป็นต้องมี ...

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

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

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

ลูกค้าควรส่งข้อความที่แตกต่างกันจำนวนมาก (ได้รับประสบการณ์คลิกที่รายการ) ทันทีที่เกิดขึ้นหรือแทนที่จะรวบรวมเพียงข้อความเดียว?

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

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

ตรวจสอบเอกสาร socket.io มันจะปรากฏให้ฉันว่าค่าใช้จ่ายข้อความอยู่บนปลายสูงของสเปกตรัมซึ่งจะชอบรวบรวมการปรับปรุงเพื่อส่งเป็นข้อความรวมเมื่อเทียบกับการปรับปรุงเดียวมากมาย

ฉันขอแนะนำให้ตรวจสอบการอัปเดตทั้งหมดที่คุณพิจารณาการจำลองแบบเช่น MMORPGs และ FPS ส่วนใหญ่ไม่รำคาญที่จะส่งผู้เล่นที่คลิกบนเหตุการณ์ X ไปยังการสังเกตลูกค้าเว้นแต่ว่าจะส่งผลให้เกิดการเปลี่ยนแปลงสถานะสำหรับวัตถุที่พวกเขาตระหนักเช่นกัน .


3
+1 คำตอบที่ดี ฉันขอแนะนำให้เริ่มต้นด้วยวิธีง่าย ๆ และปรับให้เหมาะสมจากที่นั่น ข้อความสแปมโปรดก้าวไปข้างหน้าและดูแบนด์วิดท์ของคุณจะเริ่มมอดลง นี่คือเหตุผลว่าทำไมจึงเป็นการดีที่จะจัดฉากทดสอบความเครียด คุณใช้แนวทางที่เป็นไปได้อย่างไร้เดียงสาและทำการทดสอบ คุณทำสิ่งที่เหมาะสมที่สุด; คุณทดสอบความเครียดอีกครั้งคุณปรับแต่งเพิ่มเติมล้างทำซ้ำ ถ้ามันเป็นเรื่องเล็กน้อยที่จะใช้การเพิ่มประสิทธิภาพในวันแรกไปข้างหน้า; แต่พึงระวังว่าแม้การปรับให้เหมาะสมที่สุดอาจมีข้อสันนิษฐานที่อาจไม่สามารถพิสูจน์ได้ในสภาพแวดล้อมการผลิต
วิศวกร

5

นี่คือตัวอย่างในโลกแห่งความเป็นจริง: RuneScape "ticks" ทุกๆ ~ 0.6 วินาที คุณสามารถอ่านเกี่ยวกับเรื่องนี้ที่นี่ ฉันคิดว่ามันทำให้สิ่งต่าง ๆ ง่ายขึ้นจากมุมมองของพวกเขาเช่นในสคริปต์ของพวกเขาพวกเขาอาจระบุเวลาและความล่าช้าเป็นเห็บแทนมิลลิวินาที และแน่นอนว่าด้วยอัตราการทำเครื่องหมายที่มีขนาดใหญ่ / ช้าผู้ใช้ที่มีการเชื่อมต่อที่ช้าจะไม่เสียเปรียบอย่างมากเมื่อเทียบกับผู้เล่นคนอื่น


0

วิธีหนึ่งในการทำงานคือแยกการเปลี่ยนแปลงข้อมูลจริงจากการกระจายการเปลี่ยนแปลงเหล่านั้น เมื่อวัตถุมีการเปลี่ยนแปลงให้ทำการแก้ไขและตั้งค่าสถานะ 'สกปรก' และเมื่อถึงเวลาที่จะออกอากาศการเปลี่ยนแปลงใด ๆ เพียงส่งข้อมูลสำหรับวัตถุที่ถูกตั้งค่าสถานะและล้างการตั้งค่าสถานะ ค่าที่ได้รับการเปลี่ยนแปลงหลายครั้งจะถูกรวมที่นี่โดยอัตโนมัติเนื่องจากการอัปเดตของคุณจะส่งสถานะในเวลาออกอากาศเท่านั้น คุณยังสามารถตั้งค่าสถานะวัตถุย่อยหรือคุณสมบัติแต่ละรายการเพื่อให้คุณออกอากาศสิ่งที่มีการเปลี่ยนแปลงเท่านั้น

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


ฉันจะไม่ ถ้าอย่างนั้นฉันต้องแน่ใจว่าลูกค้าทุกคนเห็นเหมือนกัน
Lanbo

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