คู่มือเกมแลค › การออกแบบการซิงก์
การคำนวณเส้นทางไม่ตรงกันในการซิงก์คำสั่ง Command sync with divergent pathing
ID สาเหตุ sy-path-mismatch · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ พัฒนาไคลเอนต์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้ารับส่งแค่ “ให้ไปที่นี่” แล้วแต่ละฝั่งคำนวณเส้นทางเอง เมื่อการคำนวณต่างกันแม้เพียงเล็กน้อย ตัวละครหรือมอนสเตอร์จะเดินไปคนละเส้นทางแล้วถูกดึงกลับมาที่ตำแหน่งที่ถูกต้อง
ทำไม การเดินแบบคลิกและการไล่ตามของมอนสเตอร์ ส่งแค่จุดหมาย และไคลเอนต์คำนวณเส้นทางแยกเอง → ผลคือ ข้อมูลภูมิประเทศต่างกัน, การชนกับตัวละครอื่น และลำดับการคำนวณที่ต่างกัน ทำให้เดินคนละเส้นทางกับเซิร์ฟเวอร์ → บนหน้าจอ มอนสเตอร์เดินทะลุกำแพงแล้ววืดไปอยู่อีกที่, ตัวละครที่คลิกเดินเลี้ยวเหมือนไถลไป
อาการ วาร์ป , ดีดกลับ
ปัจจัย ความหน่วง
ใครเจอ บางจุด/บางแชนแนล, เราคนเดียว
เกิดเมื่อไร ระหว่างเดินทาง/ย้ายแมพ
ผู้รับผิดชอบ ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ พัฒนาไคลเอนต์ (ทีมพัฒนาเกม)
งานฝั่งทีมพัฒนาเกม เซิร์ฟเวอร์: ส่งจุดกลางทาง (waypoint) ของเส้นทางไปด้วย, ซิงก์ตำแหน่งเป็นระยะ ไคลเอนต์: ค่อย ๆ ปรับส่วนที่คลาดให้เข้าที่อย่างนุ่มนวล, ใช้ข้อมูลภูมิประเทศชุดเดียวกับเซิร์ฟเวอร์
บนกราฟ พุ่งแบบสุ่มเป็นครั้งคราว · จำนวนครั้งและระยะการแก้ตำแหน่งแยกตามเอนทิตี
จุดที่ต้องดู บันทึกความต่างระหว่างตำแหน่งที่เซิร์ฟเวอร์ส่งมากับตำแหน่งที่ไคลเอนต์คำนวณ ของแต่ละเอนทิตี แล้วปักพิกัดที่เกิดการแก้ตำแหน่งลงบนแผนที่ ถ้าสรุปผลเส้นทางหรือตำแหน่งของทั้งสองฝั่งเป็น checksum แล้วเทียบเป็นระยะ จะหาจังหวะที่เริ่มคลาดได้ สัญญาณว่าใช่ การแก้ตำแหน่งกระจุกอยู่ที่ภูมิประเทศบางแบบ (ขอบต่างระดับ, ทางแคบ, ทางลาด) หรือที่ที่คนแน่น และเกิดซ้ำที่จุดเดิมแม้กับผู้เล่นที่เมตริกเครือข่ายปกติ สัญญาณว่าไม่ใช่ แก้ตำแหน่งเฉพาะจังหวะที่แพ็กเก็ตหายหรือจิตเตอร์พุ่งโดยไม่เกี่ยวกับสถานที่: น่าจะเป็นปัญหาเน็ต ถ้ามอนสเตอร์ตัวเดียวกระโดดบนจอของหลายคนพร้อมกัน ให้ดูว่าสิทธิ์ควบคุมมอนสเตอร์อยู่ที่ไคลเอนต์ที่ช้าหรือไม่ วิธีตรวจ ต้องมี log หรือเมตริกจากเซิร์ฟเวอร์/ไคลเอนต์เกม
รายละเอียดเพิ่มเติม วิธีนี้เป็นเหตุผลหนึ่งที่เกมคลิกเดินและเกม tab target ไม่ค่อยไวต่อปิง แต่ไม่มีอะไรรับประกันว่าผลทั้งสองฝั่งจะตรงกัน จึงจำเป็นต้องมีกลไกปรับตำแหน่งให้ตรงกันเป็นครั้งคราว การคำนวณแบบ floating point อาจให้ผลต่างกันเล็กน้อยตามชนิด CPU, คอมไพเลอร์ และการตั้งค่า optimization ของคอมไพเลอร์ (รวมถึงความต่างระหว่าง debug build กับ release build) ในโครงสร้างที่รับส่งแค่อินพุตและถือว่าผลการคำนวณทั้งสองฝั่งเหมือนกันทุกประการ อย่าง lockstep และ rollback ความต่างเล็ก ๆ นี้อาจสะสมจนสถานะเกมบนสองจอแยกออกจากกัน (desync)
แหล่งอ้างอิง Deterministic Lockstep Gaffer On Games แม้จะ deterministic บนเครื่องเดียวกัน ถ้าคอมไพเลอร์, OS หรือ CPU ต่างกัน ผล floating point ก็อาจต่างกัน State Synchronization Gaffer On Games ถ้าส่งสถานะไปพร้อมอินพุต ก็ปรับทั้งสองฝั่งให้ตรงกันได้โดยไม่ต้อง deterministic สมบูรณ์ Peeking into VALORANT's Netcode Riot Games เมื่อแพ็กเก็ตหาย หรือตัวละครสองตัวพยายามไปที่จุดเดียวกัน simulation ของเซิร์ฟเวอร์กับไคลเอนต์จะคลาดกันจนต้องแก้ 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond Game Developer ความต่างเล็กมากขยายใหญ่ขึ้นตามเวลา จนเส้นทางของคนงาน (worker) ค่อย ๆ คลาด, เทียบโลก, เอนทิตี และ pathfinding ด้วย checksum เพื่อหาการคลาด (out-of-sync) Floating Point Determinism Gaffer On Games โค้ด floating point เดียวกันอาจให้ผลต่างกันตามคอมไพเลอร์, สถาปัตยกรรม CPU และ debug/release build, มีกรณีที่ CPU ของ AMD และ Intel ให้ค่าฟังก์ชัน transcendental ต่างกันเล็กน้อย /fp (Specify floating-point behavior) Microsoft /fp:fast อาจสลับหรือรวมลำดับการคำนวณ floating point จนผลต่างจากการตั้งค่า /fp แบบอื่น และการคำนวณที่รวมด้วย FMA ก็อาจต่างจากการคูณแล้วบวกแยกกัน
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: การออกแบบการซิงก์
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (วาร์ป)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง