ตอนนี้ฉันกำลังวางแผนเล่นเกมออนไลน์พร้อมกัน และนี่คือคำถาม มันสมเหตุสมผลหรือไม่ที่จะสร้างตรรกะของเกมทั้งหมดบนเซิร์ฟเวอร์และเพียงแค่ส่งอินพุตจากไคลเอนต์ไปยังเซิร์ฟเวอร์ ข้อดีข้อเสียใดหรือมีเหตุผลใดบ้างที่ฉันไม่ควรทำเช่นนั้น
ตอนนี้ฉันกำลังวางแผนเล่นเกมออนไลน์พร้อมกัน และนี่คือคำถาม มันสมเหตุสมผลหรือไม่ที่จะสร้างตรรกะของเกมทั้งหมดบนเซิร์ฟเวอร์และเพียงแค่ส่งอินพุตจากไคลเอนต์ไปยังเซิร์ฟเวอร์ ข้อดีข้อเสียใดหรือมีเหตุผลใดบ้างที่ฉันไม่ควรทำเช่นนั้น
คำตอบ:
คุณไม่ต้องการส่งอินพุตผู้เล่นไปยังเซิร์ฟเวอร์ สิ่งที่คุณอาจต้องการทำคือส่งตัวแทนที่เป็นนามธรรมของสิ่งที่ผู้เล่นต้องการทำไปยังเซิร์ฟเวอร์แล้วเรียกใช้ลอจิกที่นั่น
ในทำนองเดียวกันคุณไม่จำเป็นต้องส่งทุกสิ่งที่ลูกค้าต้องการทำ ตัวอย่างเช่นคุณสามารถส่งข้อความบางประเภทที่บอกว่า "NPC X ตาย" และลูกค้ากำหนดว่าจะเล่นแอนิเมชัน / เสียงใด สิ่งที่ต้องการ
เคล็ดลับคือการหาบรรทัดที่แบนด์วิดท์และพลังการประมวลผล (บนเซิร์ฟเวอร์) เป็นคนดีโดยป้องกันไม่ให้คนโกง โดยปกติแล้วคุณจะทำการตัดสินใจที่มีสิทธิ์ในการเปลี่ยนแปลงเกมบนเซิร์ฟเวอร์เท่านั้นและปล่อยให้สิ่งที่เป็นภาพเสริมทั้งหมดไปยังลูกค้า
มีคำถามที่เฉพาะเจาะจงมากขึ้นในหัวข้อนี้ทั่วไซต์ ตัวอย่างเช่น:
ควรทำการตรวจจับการชนกันของเซิร์ฟเวอร์หรือทำงานร่วมกันระหว่างไคลเอ็นต์ / เซิร์ฟเวอร์หรือไม่
คุณได้คำตอบแล้ว แต่คำตอบที่แท้จริงคือ "ลองด้วยตัวเอง" สิ่งต่าง ๆ จากเกมกับเกม
ฉันทำเกมแบบผู้เล่นหลายคนสองเกมสำหรับหลักสูตรการออกแบบเกมเครือข่ายแบบกระจาย สิ่งที่ท้าทายที่สุดคือการเล่นเกมแอ็คชั่นแบบเรียลไทม์ซึ่งผู้เล่นหลายคนมีส่วนร่วมและส่งอินพุตเหมือนนรก เมื่อพูดถึงประเด็นนั้นทุกอย่างจะกลายเป็นปัญหา ตามที่คุณเห็นลิงค์แรกที่ 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 ,
ข้อดี:
จุดด้อย:
ตรรกะด้านเซิร์ฟเวอร์ยังสร้างปัญหาเรื่องความสามารถในการขยาย - คุณต้องทำงานทั้งหมดให้กับลูกค้าทั้งหมดบนเซิร์ฟเวอร์ของคุณ - ข้อที่ให้ลูกค้าแต่ละรายทำงานร่วมกันโดยรวมของตัวเอง
ขึ้นอยู่กับเกมที่คุณต้องการสร้างและส่วนใดของเกม หากการพัฒนา RTS (หรือเกมใด ๆ ที่มีโมเดลแบบล็อค) คุณควรส่งอินพุตและขั้นตอนการจำลองที่อินพุตได้รับแน่นอน
หากคุณต้องการยิงปืนคุณสามารถใช้ทั้งฟังก์ชั่นอินพุตและนามธรรม หากคุณใช้ Unreal Tournament 3 เป็นกรณีพวกเขาสร้างมัลติเพลเยอร์เป็นหลักผ่านการเรียกใช้ฟังก์ชันที่จำลองแบบ
สำหรับการเคลื่อนไหวพวกเขารับอินพุตของผู้เล่น (บีบอัดเป็นบิตสำหรับแต่ละการกระทำ) การหมุนเดลต้าการเร่งความเร็วและการประทับเวลาและส่งไปยังเซิร์ฟเวอร์
สำหรับจุดประสงค์อื่น ๆ เช่นอาวุธพวกมันจะซิงโครไนซ์เมื่อคุณยิง (AFAIK ยังไม่ได้เจาะลึกเข้าไปในส่วนนี้)
สำหรับค่าคงที่ / เปลี่ยนแปลงที่น้อยลงบ่อยๆเช่นความสมบูรณ์พวกเขาส่งตัวแปรไปยังไคลเอนต์หรือเซิร์ฟเวอร์ขึ้นอยู่กับสิ่งที่โปรแกรมเมอร์ระบุไว้
และสำหรับเกมที่ไม่ใช่ RTS ให้จำการคาดการณ์ของลูกค้า