Bug Pintu Perjalanan Waktu di Half-Life 2
(mastodon.gamedev.place)- Bug aneh ditemukan pada adegan awal Half-Life 2 di mana pintu tidak terbuka sehingga progres terhenti
- Penyebabnya adalah ujung kaki penjaga yang berdiri di dalam jalur pintu bertabrakan dengan pintu saat terbuka, sehingga pintu menutup lagi dan terkunci
- Tabrakan yang sama juga ada di kode asli, tetapi hasilnya berbeda karena perbedaan presisi antara operasi floating-point x87 tahun 2004 dan operasi SSE tahun 2013
- Di lingkungan x87, sedikit rotasi mendorong kaki bergeser tipis sehingga tabrakan teratasi, tetapi di SSE rotasinya tidak cukup sehingga pintu justru menutup
- Kasus ini menjadi contoh representatif yang menunjukkan bagaimana presisi floating-point dan perbedaan compiler memengaruhi perilaku game secara nyata
Bug yang ditemukan saat proses porting Half-Life 2 ke VR
- Pada 2013, saat Valve bereksperimen mem-porting Team Fortress 2 ke VR, Half-Life 2 dan Portal 1 yang memakai engine yang sama juga bisa dijalankan di VR
- Portal 1 membuat pusing sampai nyaris tidak bisa dimainkan di VR karena distorsi sudut pandang
- Half-Life 2 berjalan cukup baik, dan imersi khas VR meningkat pada adegan perahu, menumpuk kotak, serta pertarungan melawan manhack
- Saat pengujian, seorang developer memainkan game dari awal sampai akhir di VR lalu menemukan kondisi tidak bisa lanjut pada adegan stasiun kereta di awal game
Analisis penyebab pintu tidak terbuka
- Dalam skenario normal, penjaga (sebenarnya Barney) mengetuk pintu dan berkata “masuklah”, lalu ketika pemain masuk ke ruangan, permainan lanjut ke skrip berikutnya
- Namun dalam situasi bug, pintu bergetar lalu terkunci sambil menutup rapat, penjaga terus menunjuk ke pintu, dan pemain pun terjebak
- Bahkan setelah source code asli Half-Life 2 dibangun ulang, masalah yang sama tetap muncul, sehingga ini terlihat seperti bug yang muncul karena menelusuri waktu ke masa lalu
Akar masalah: perubahan cara operasi floating-point
- Saat rilis pada 2004, Half-Life 2 memakai set instruksi matematika x87, dengan struktur yang mencampur presisi 32, 64, dan 80 bit
- Pada build setelah 2013, set instruksi SSE dipakai sebagai default, sehingga presisi perhitungannya dibatasi jelas ke 32 atau 64 bit
- Di kedua lingkungan, pintu dan ujung kaki penjaga sama-sama bertabrakan, tetapi hasilnya berbeda karena perbedaan sangat kecil dalam perhitungan physics engine
- Di x87, saat terjadi tabrakan penjaga berputar sangat sedikit sehingga kakinya keluar dari jalur pintu dan pintu terbuka
- Di SSE, besar rotasinya sedikit lebih kecil sehingga kaki masih menyentuh pintu, lalu pintu menutup lagi dan terkunci
Perbaikan dan penyelesaian
- Setelah penyebabnya ditemukan, masalah diselesaikan dengan perbaikan sederhana: menggeser posisi penjaga sekitar 1 mm ke belakang
- Proses debugging memakan cukup banyak waktu, termasuk harus mempelajari lagi cara memakai tool lama
- Kasus ini menunjukkan bahwa perbedaan presisi dan perubahan pengaturan compiler dapat mengubah perilaku kode lama
Reaksi komunitas
- Para developer banyak yang sepakat dengan komentar, “masalahnya selalu karena presisi floating-point”
- Sebagian menyebut contoh perubahan perhitungan tabrakan pada remake Sonic 1, 2, dan 3 sebagai kasus serupa
- Bersamaan dengan pelajaran bahwa kodenya sama, tetapi compilernya berbeda, kasus ini dinilai sebagai pengingat akan sulitnya memelihara kode legacy
- Developer lain juga mengaitkannya dengan alasan desain di Fallout 4 dan game lain agar NPC tidak melewati pintu karena masalah semacam ini
- Secara umum, banyak yang menilai ini sebagai salah satu kisah bug paling menarik
1 komentar
Komentar Hacker News
Dulu saat masih mengembangkan game, saya ingat pernah mengalami kegagalan assertion yang hanya terjadi di PC tertentu karena kesalahan perhitungan FPU
Penyebabnya adalah perangkat lunak input tulisan tangan yang menyuntikkan DLL ke semua proses lalu me-reset mode FPU ke nilai bawaan
Pada akhirnya, kode pengaturan FPU dipindahkan dari tahap inisialisasi ke loop event untuk menghindari dampak dari DLL pihak ketiga
Salah satu tujuan saya adalah membuat Valve menggunakan Nix
Menurut saya ini akan terlihat lebih menarik sekarang karena dukungan Windows sedang berjalan
Dengan begitu, bukan hanya source code asli, tetapi juga toolchain dan dependensi pada saat itu bisa direproduksi sepenuhnya, sehingga akar penyebab bug seperti ini akan jauh lebih mudah ditemukan
Ini mengingatkan pada meme “DOOR STUCK”
Video terkait
Saya penasaran apakah “Half-Life 2 VR beta” benar-benar bisa dimainkan
Kalau bisa, saya heran kenapa saya tidak tahu; kalau tidak, saya juga heran kenapa sampai sekarang belum bisa
Saya juga sangat ingin mencoba Portal VR. Banyak yang bilang bikin mabuk gerak, tapi saya kebal terhadap motion sickness di VR jadi rasanya layak dicoba
Kualitasnya cukup tinggi sampai membuat saya memainkan HL2 lagi setelah sekian lama
Saat beralih dari x87 ke SSE, wajar kalau beberapa perhitungan jadi rusak
Hal yang sama juga pernah terjadi di TF2; build Linux menggunakan SSE sehingga perhitungan amunisinya sedikit berbeda
Kotak kecil bisa memberi +40 atau +41, dan itu berbeda tergantung OS server
Setiap kali masuk ke server baru, ada keseruan tersendiri menebak OS apa yang dipakai
Kalau cuma ganti dari x87 ke SSE saja sudah bisa merusak game, menarik juga bagaimana konversi x86→ARM bisa berjalan sebaik itu
Ia memakai register 80-bit sehingga presisinya lebih tinggi, tetapi menunjukkan perilaku ganjil seperti kehilangan presisi saat di-spill ke memori
Saya juga pernah mengalami bug presisi serupa saat men-debug software synthesizer
Simulasi rangkaian RC seharusnya mengganti status saat mendekati 0, tetapi di CPU tertentu nilai denormal tidak di-flush sehingga syaratnya tidak pernah terpenuhi
Pada akhirnya saya asal mengatur ambang menjadi sekitar 0.7 dan 0.01, lalu semuanya bekerja baik di semua platform
Sedikit meta, saya ingin membuat klon Twitter yang langsung memban pengguna kalau mereka ngeblog dalam beberapa paragraf