ตรรกะของเกมบนเซิร์ฟเวอร์! ดีหรือไม่ดี


25

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

คำตอบ:


37

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

ในทำนองเดียวกันคุณไม่จำเป็นต้องส่งทุกสิ่งที่ลูกค้าต้องการทำ ตัวอย่างเช่นคุณสามารถส่งข้อความบางประเภทที่บอกว่า "NPC X ตาย" และลูกค้ากำหนดว่าจะเล่นแอนิเมชัน / เสียงใด สิ่งที่ต้องการ

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

มีคำถามที่เฉพาะเจาะจงมากขึ้นในหัวข้อนี้ทั่วไซต์ ตัวอย่างเช่น:

ควรทำการตรวจจับการชนกันของเซิร์ฟเวอร์หรือทำงานร่วมกันระหว่างไคลเอ็นต์ / เซิร์ฟเวอร์หรือไม่

ใครคำนวณ AI ใน MMO ได้บ้าง

ผู้ให้บริการเกมควรเป็นผู้มีอำนาจหรือเป็นลูกค้าใบ้อีกคน


4
+1 ชนะฉันได้ไหม นอกจากนี้ขึ้นอยู่กับสไตล์ของเกมคุณอาจต้องการ / จำเป็นต้องคาดเดาฝั่งไคลเอ็นต์
John McDonald

14

คุณได้คำตอบแล้ว แต่คำตอบที่แท้จริงคือ "ลองด้วยตัวเอง" สิ่งต่าง ๆ จากเกมกับเกม

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

คำแนะนำของฉันคือ:

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

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

ขั้นตอนที่ 3
ตอนนี้เกมของคุณใช้ได้ดีสำหรับเครือข่ายที่รวดเร็วซึ่งมีความล่าช้า (1-50) มิลลิวินาที แต่จะได้รับอีกต่อไปหากมีการสูญเสียแพ็คเก็ต, เวลาแฝงสูงหรือการคำนวณใช้เวลานานในเซิร์ฟเวอร์ ... ect ในสถานการณ์เหล่านั้นคุณจะสังเกตเห็นเมื่อคุณกดลูกศรซ้ายคุณจะเห็นตัวละครของคุณเคลื่อนไหวไปทางซ้ายด้วยความล่าช้า 200 ms ความล่าช้าระหว่างแพ็คเก็ตของคุณไปยังเซิร์ฟเวอร์เวลาการคำนวณและกลับมาหาคุณพร้อมตำแหน่งสุดท้าย นี่เป็นข้อเสียข้อเสียที่เลวร้ายที่สุดของการออกแบบเซิร์ฟเวอร์ที่ได้รับอนุญาต ผู้เล่นต้องการให้ตัวละครของเขาเดินไปทางซ้ายทันทีที่เขากดไปทางซ้ายคุณไม่สามารถทำให้เขารอได้ โชคดีที่ลูกค้ามีรหัสเดียวกันกับเซิร์ฟเวอร์ดังนั้นทำไมไม่ลองใช้มันกับลูกค้าทันทีและแก้ไขผลลัพธ์สุดท้ายด้วยคำตอบจากเซิร์ฟเวอร์? นั่นคือการคาดการณ์อินพุตพื้นฐาน ลูกค้ากดซ้ายรหัสในด้านของเขาจะย้ายเขาไปทางซ้าย หลังจากเวลาผ่านไป 200 มิลลิวินาทีตำแหน่งจริงมาจากเซิร์ฟเวอร์และไคลเอนต์แก้ไขตำแหน่งของมันด้วย หากทุกอย่างไปได้ด้วยดีลูกค้าจะไม่สังเกตเห็นอะไรเลย "ขั้นตอนที่ 2" จะช่วยเราในเรื่องนี้

อึมีบทเรียนมากมายและสิ่งที่เกี่ยวกับเรื่องนี้ แต่มี 2 ฉันชอบ:

ดีจริงๆครอบคลุมจุดด่างดำ: วาล์ว Source Engine หลายคนเครือข่าย
ชนิดของประวัติศาสตร์สนุกในการอ่านและคุ้มค่า: 1500 ธนูบน 28.8 ,


3

ข้อดี:

  • วิธีนี้เป็นข้อพิสูจน์การละเมิดลิขสิทธิ์มากกว่า (ส่วนใหญ่)
  • คุณสามารถใช้การอัปเดตได้ง่ายขึ้น
  • ชุมชนส่วนกลาง

จุดด้อย:

  • ต้องการแบนด์วิดธ์ขนาดใหญ่
  • ผู้ใช้บางคนสามารถเกลียดวิธีการนั้น (ความเป็นส่วนตัวและเนื้อหา)
  • ปัญหาเกี่ยวกับการเล่นเกมท้องถิ่น (ฝ่าย LAN), ผู้เล่นคนเดียว

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

2

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


มันตลกเมื่อฉันถามคำถามที่คล้ายกันที่นี่ในปี 2559 ทุกคนแค่บอกฉันว่า "ไม่เชื่อใจลูกค้า"
newguy

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

2

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

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

และสำหรับเกมที่ไม่ใช่ RTS ให้จำการคาดการณ์ของลูกค้า

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