Megapack: Factorio แก้ปัญหาผู้เล่นหลายคน 200 คนได้อย่างไร

Megapack: Factorio แก้ปัญหาผู้เล่นหลายคน 200 คนได้อย่างไร
ในเดือนพฤษภาคมปีนี้ ฉันได้เข้าร่วมเป็นผู้เล่นใน เหตุการณ์ MMO ของ KatherineOfSky. ฉันสังเกตเห็นว่าเมื่อจำนวนผู้เล่นถึงจำนวนที่กำหนด ทุกๆ สองสามนาที ผู้เล่นบางคนจะ "หลุด" โชคดีสำหรับคุณ (แต่ไม่ใช่สำหรับฉัน) ฉันเป็นหนึ่งในผู้เล่นเหล่านั้น ทุกเวลาแม้จะมีการเชื่อมต่อที่ดี ฉันถือเป็นความท้าทายส่วนตัวและเริ่มมองหาสาเหตุของปัญหา หลังจากแก้ไขข้อบกพร่อง ทดสอบ และแก้ไขเป็นเวลาสามสัปดาห์ ในที่สุดข้อบกพร่องก็ได้รับการแก้ไข แต่การเดินทางไม่ง่ายอย่างนั้น

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

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

Megapack: Factorio แก้ปัญหาผู้เล่นหลายคน 200 คนได้อย่างไร
ปัญหาค่อนข้างพื้นฐาน และฉันใช้เวลา 2 สัปดาห์ในการแก้ไข ค่อนข้างเป็นเรื่องทางเทคนิค ดังนั้นฉันจะอธิบายรายละเอียดทางเทคนิคที่น่าสนใจด้านล่าง แต่ก่อนอื่น คุณต้องทราบว่าตั้งแต่เวอร์ชัน 0.17.54 ซึ่งเปิดตัวเมื่อวันที่ 4 มิถุนายน เมื่อเผชิญกับปัญหาการเชื่อมต่อชั่วคราว ผู้เล่นหลายคนจะมีความเสถียรมากขึ้น และการซ่อนการหน่วงเวลานั้นบั๊กน้อยลงมาก (การเบรกและการเทเลพอร์ตน้อยลง) นอกจากนี้ ฉันได้เปลี่ยนวิธีการซ่อนความล่าช้าในการต่อสู้ และหวังว่าสิ่งนี้จะทำให้มันราบรื่นขึ้นอีกเล็กน้อย

Multiplayer Mega Pack - รายละเอียดทางเทคนิค

เพื่อให้พูดง่ายๆ ผู้เล่นหลายคนในเกมทำงานในลักษณะนี้: ไคลเอนต์ทั้งหมดจำลองสถานะของเกมโดยรับและส่งเฉพาะอินพุตของผู้เล่น (เรียกว่า "การดำเนินการอินพุต" การดำเนินการป้อนข้อมูล). งานหลักของเซิร์ฟเวอร์คือการถ่ายโอน การดำเนินการป้อนข้อมูล และตรวจสอบให้แน่ใจว่าไคลเอนต์ทั้งหมดดำเนินการอย่างเดียวกันในรอบเดียวกัน คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในโพสต์ เอฟเอฟเอฟ-149.

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

Megapack: Factorio แก้ปัญหาผู้เล่นหลายคน 200 คนได้อย่างไร
Factorio มีสถานะของเกม สถานะของเกม คือสถานะที่สมบูรณ์ของแผนที่ ผู้เล่น เอนทิตี และอื่น ๆ มีการจำลองเชิงกำหนดในไคลเอนต์ทั้งหมดตามการกระทำที่ได้รับจากเซิร์ฟเวอร์ สถานะของเกมเป็นสิ่งศักดิ์สิทธิ์ และหากเริ่มแตกต่างจากเซิร์ฟเวอร์หรือไคลเอนต์อื่น ๆ การซิงโครไนซ์จะเกิดขึ้น

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

ในการทำเช่นนี้ เราจะเก็บสำเนาของข้อมูลที่สร้างขึ้นไว้ การดำเนินการป้อนข้อมูล ในคิวล่าช้า

Megapack: Factorio แก้ปัญหาผู้เล่นหลายคน 200 คนได้อย่างไร
นั่นคือในตอนท้ายของกระบวนการในฝั่งไคลเอนต์ รูปภาพจะมีลักษณะดังนี้:

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

ทั้งหมดนี้ทำซ้ำในทุกการวัด

ยากมาก? อย่าผ่อนคลาย นั่นไม่ใช่ทั้งหมด เพื่อชดเชยการเชื่อมต่ออินเทอร์เน็ตที่ไม่เสถียร เราได้สร้างสองกลไก:

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

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

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

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

  1. ผู้เล่นกำลังประสบปัญหาการเชื่อมต่อ
  2. กลไกสำหรับการข้ามรอบและการควบคุมความล่าช้าในการส่งสัญญาณไปกลับเข้ามามีบทบาท
  3. คิวสถานะการหน่วงเวลาไม่ได้คำนึงถึงกลไกเหล่านี้ สิ่งนี้ทำให้การดำเนินการบางอย่างถูกลบออกก่อนเวลาอันควรหรือทำงานผิดลำดับ ส่งผลให้การทำงานไม่ถูกต้อง สถานะแฝง.
  4. ผู้เล่นไม่มีปัญหาการเชื่อมต่อและจำลองได้ถึง 400 รอบเพื่อให้ทันกับเซิร์ฟเวอร์
  5. ในแต่ละรอบ การดำเนินการใหม่จะถูกสร้างขึ้นและเตรียมส่งไปยังเซิร์ฟเวอร์ ซึ่งจะเปลี่ยนการเลือกเอนทิตี
  6. ไคลเอนต์ส่งเมกะแพ็กเก็ตของการเปลี่ยนแปลงการเลือกเอนทิตีมากกว่า 400 รายการไปยังเซิร์ฟเวอร์ (และด้วยการดำเนินการอื่นๆ: สถานะเริ่มทำงาน สถานะเดิน ฯลฯ ประสบปัญหานี้เช่นกัน)
  7. เซิร์ฟเวอร์ได้รับการดำเนินการอินพุต 400 รายการ เนื่องจากไม่ได้รับอนุญาตให้ข้ามการดำเนินการอินพุตเดียว จึงสั่งให้ไคลเอนต์ทั้งหมดดำเนินการเหล่านี้และส่งผ่านเครือข่าย

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

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

ที่มา: will.com

เพิ่มความคิดเห็น