1 คะแนน โดย GN⁺ 2025-11-24 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • พบ บั๊กประหลาด ในฉากช่วงต้นของ Half-Life 2 ที่ทำให้ประตูไม่เปิดและเกมดำเนินต่อไม่ได้
  • สาเหตุคือเมื่อประตูเปิด ปลายเท้าของยามที่ยืนอยู่ด้านในชนกับเส้นทางการเคลื่อนที่ของประตู ทำให้ประตูปิดกลับและล็อกอีกครั้ง
  • แม้ในโค้ดต้นฉบับจะมีการชนกันแบบเดียวกันอยู่แล้ว แต่ผลลัพธ์กลับต่างกันเพราะความต่างของความแม่นยำระหว่าง การคำนวณเลขทศนิยมลอยตัวแบบ x87 ในปี 2004 และ การคำนวณแบบ SSE ในปี 2013
  • ในสภาพแวดล้อม x87 จะเกิดการหมุนเล็กน้อยทำให้เท้าถูกดันออกไปและการชนหายไป แต่ใน SSE ปริมาณการหมุนไม่พอ จึงลงเอยด้วยการที่ประตูปิด
  • กรณีนี้เป็นตัวอย่างเด่นที่แสดงให้เห็นว่า ความแม่นยำของเลขทศนิยมลอยตัวและความต่างของคอมไพเลอร์ ส่งผลต่อพฤติกรรมจริงของเกมได้อย่างไร

บั๊กที่พบระหว่างการพอร์ต Half-Life 2 ไปยัง VR

  • ระหว่างการทดลองพอร์ต Team Fortress 2 ไปยัง VR ที่ Valve ในปี 2013 เกมที่ใช้เอนจินเดียวกันอย่าง Half-Life 2 และ Portal 1 ก็สามารถรันบน VR ได้ด้วย
    • Portal 1 ทำให้เวียนหัวจนแทบเล่นใน VR ไม่ได้ เพราะมุมมองบิดเบือน
    • Half-Life 2 กลับทำงานได้ค่อนข้างดี และฉากเรือ การเรียงกล่อง รวมถึงการต่อสู้กับ manhack ก็ยิ่งเพิ่มความสมจริงแบบ VR
  • ระหว่างการทดสอบ นักพัฒนาเล่นเกมใน VR ตั้งแต่ต้นจนจบ และพบว่า ติดค้างเล่นต่อไม่ได้ในฉากสถานีรถไฟช่วงต้นเกม

การวิเคราะห์สาเหตุที่ประตูไม่เปิด

  • ในเหตุการณ์ตามปกติ ยามคนหนึ่ง (จริง ๆ แล้วคือ Barney) จะเคาะประตูแล้วพูดว่า “เข้าไปสิ” จากนั้นเมื่อผู้เล่นเข้าไปในห้อง เกมจะดำเนินต่อด้วยสคริปต์ถัดไป
  • แต่ในกรณีบั๊ก ประตูจะ กระตุกแล้วล็อกจนปิดสนิท ยามยังคงชี้ไปที่ประตู และผู้เล่นก็ติดอยู่ข้างนอก
  • เมื่อนำซอร์สโค้ดต้นฉบับของ Half-Life 2 มาสร้างใหม่ก็ยังเกิดปัญหาเดียวกัน ทำให้ดูเหมือนเป็น บั๊กที่เหมือนเกิดขึ้นจากการย้อนเวลา จนสร้างความสับสน

ต้นตอที่แท้จริง: การเปลี่ยนวิธีคำนวณเลขทศนิยมลอยตัว

  • ตอนที่ Half-Life 2 วางจำหน่ายในปี 2004 เกมใช้ ชุดคำสั่งคณิตศาสตร์ x87 ซึ่งเป็นโครงสร้างที่มีความแม่นยำปะปนกันทั้ง 32, 64 และ 80 บิต
  • ในบิลด์หลังปี 2013 มีการใช้ ชุดคำสั่ง SSE เป็นค่าเริ่มต้น ทำให้ความแม่นยำของการคำนวณถูกจำกัดไว้อย่างชัดเจนที่ 32 หรือ 64 บิต
  • ทั้งสองสภาพแวดล้อมต่างก็มีการชนกันระหว่างประตูกับปลายเท้าของยาม แต่ ความต่างเล็กน้อยในการคำนวณของฟิสิกส์เอนจิน ทำให้ผลลัพธ์ไม่เหมือนกัน
    • ใน x87 เมื่อเกิดการชน ยามจะหมุนเพียงเล็กน้อยจนเท้าหลุดพ้นจากประตู ทำให้ประตูเปิดได้
    • ใน SSE ปริมาณการหมุนนั้นน้อยลงอีกนิด ทำให้เท้ายังแตะประตูอยู่ และประตูก็ปิดกลับพร้อมล็อก

การแก้ไขและการแก้ปัญหา

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

ปฏิกิริยาจากชุมชน

  • นักพัฒนาหลายคนเห็นพ้องว่า “สุดท้ายปัญหาก็มักจะเป็นเรื่อง ความแม่นยำของเลขทศนิยมลอยตัว
  • บางคนยกตัวอย่างกรณีการเปลี่ยนการคำนวณการชนในรีเมกของ Sonic 1·2·3 ว่าคล้ายกัน
  • หลายความเห็นมองว่านี่เป็นบทเรียนว่า “โค้ดเหมือนเดิม แต่คอมไพเลอร์ไม่เหมือนเดิม” และเป็นตัวอย่างที่เตือนถึง ความยากในการดูแลโค้ดแบบเลกาซี
  • นักพัฒนาคนอื่น ๆ ยังเชื่อมโยงไปถึงเหตุผลที่เกมอย่าง Fallout 4 ออกแบบไม่ให้ NPC เดินผ่านประตูได้ เพื่อหลีกเลี่ยงปัญหาแบบนี้
  • โดยรวมแล้ว หลายคนมองว่านี่คือ “หนึ่งในเรื่องเล่าบั๊กที่น่าสนใจที่สุด”

1 ความคิดเห็น

 
GN⁺ 2025-11-24
ความคิดเห็นจาก Hacker News
  • สมัยก่อนตอนที่ทำพัฒนาเกม เคยจำได้ว่ามีกรณี assert ล้มเหลวจาก ข้อผิดพลาดการคำนวณของ FPU ที่เกิดขึ้นเฉพาะบนพีซีบางเครื่อง
    สาเหตุคือซอฟต์แวร์รับลายมือเขียนได้ฉีด DLL เข้าไปในทุกโปรเซส และ รีเซ็ต โหมด FPU กลับเป็นค่าเริ่มต้น
    สุดท้ายก็เลยย้ายโค้ดตั้งค่า FPU จากขั้นตอนเริ่มต้นระบบไปไว้ใน event loop เพื่อหลีกเลี่ยงผลกระทบจาก DLL ของบุคคลที่สาม

    • แกะรอยได้ยอดเยี่ยมมาก สถานะ FPU แบบ global นี่สร้าง เรื่องปวดหัว มาเยอะจริง ๆ
  • หนึ่งในเป้าหมายของฉันคือทำให้ Valve หันมาใช้ Nix
    คิดว่าตอนนี้น่าจะน่าสนใจขึ้นเพราะกำลังมีการรองรับ Windows
    ถ้าเป็นแบบนั้น ก็จะสามารถจำลองซ้ำได้ครบถ้วนไม่ใช่แค่ซอร์สต้นฉบับ แต่รวมถึง toolchain และ dependency ในยุคนั้นด้วย เลยคิดว่าน่าจะช่วยหาสาเหตุรากของบั๊กแบบนี้ได้ง่ายขึ้นมาก

  • ทำให้นึกถึงมีม “DOOR STUCK”
    วิดีโอที่เกี่ยวข้อง

  • สงสัยว่า “Half-Life 2 VR เบตา” เล่นได้จริงหรือเปล่า
    ถ้าเล่นได้ก็สงสัยว่าทำไมฉันไม่เคยรู้มาก่อน แต่ถ้ายังเล่นไม่ได้ก็สงสัยว่าทำไมถึงยังไม่ทำ
    อยากลอง Portal VR มากเหมือนกัน หลายคนบอกว่าเวียนหัวหนัก แต่ฉันแทบไม่เมา VR เลย น่าจะลองได้

    • ไม่แน่ใจเรื่องเบตา แต่ตอนนี้มี ม็อดแปลง HL2 VR ที่ยอดเยี่ยมและเล่นได้ทันที
      คุณภาพดีจนทำให้อยากกลับไปเล่น HL2 อีกรอบเลย
    • มี ม็อด Portal 2 VR ด้วย ฉันเล่นจนจบแล้ว และรู้สึกสบายกว่าที่คิดมาก
  • ตอนย้ายจาก x87 ไป SSE แล้วการคำนวณบางส่วนพัง เป็นเรื่องที่เกิดขึ้นได้บ่อย
    ใน TF2 ก็เคยเกิดแบบเดียวกัน โดยบิลด์บน Linux ใช้ SSE ทำให้การคำนวณกระสุนต่างออกไปเล็กน้อย

    • แปลกใจที่ใช้ float มาคำนวณกระสุน
    • ความต่างที่สังเกตเห็นได้จริง ๆ มีแค่ค่า metal ของ Engineer
      กล่องเล็กจะให้ +40 หรือ +41 แล้วแต่ OS ของเซิร์ฟเวอร์
      ทุกครั้งที่เข้าเซิร์ฟเวอร์ใหม่ก็สนุกดีที่จะเดาว่าเป็น OS อะไร
  • แค่เปลี่ยนจาก x87 ไปเป็น SSE เกมก็พังแล้ว เลยยิ่งน่าทึ่งที่ การแปลง x86→ARM ทำงานได้ดีขนาดนั้น

    • มีแค่ x87 FPU เท่านั้นที่เป็น หน่วยคำนวณ floating-point สุดแปลก
      มันใช้รีจิสเตอร์ 80 บิต จึงมีความแม่นยำสูงกว่า แต่ก็มีพฤติกรรมประหลาดอย่างเช่นสูญเสียความแม่นยำเมื่อ spill ลงหน่วยความจำ
    • ความต่างของความแม่นยำอาจทำให้ค่าตัวเลขต่างกันเพียงเล็กน้อยมาก และนั่นก็อาจลามไปเป็นปัญหาอย่าง การชนของประตู ได้
      ตอนก่อนหน้านี้ที่ฉันดีบักซอฟต์แวร์ซินธิไซเซอร์ ก็เคยเจอ บั๊กด้านความแม่นยำ คล้าย ๆ กัน
      การจำลองวงจร RC ต้องให้ค่าเข้าใกล้ 0 มากพอถึงจะเปลี่ยนสถานะได้ แต่บน CPU บางตัว ค่า denormal ไม่ถูก flush เลยไม่เข้าเงื่อนไข
      ท้ายที่สุดก็ปรับค่า threshold แบบคร่าว ๆ เป็นประมาณ 0.7 กับ 0.01 แล้วมันก็ทำงานได้ดีบนทุกแพลตฟอร์ม
  • พูดแบบเมตา ๆ หน่อย ฉันกำลังจะทำ ทวิตเตอร์โคลน และคิดจะใส่ฟีเจอร์แบนทันทีถ้าใครโพสต์บล็อกยาวหลายย่อหน้า

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