- Half-Life 2'nin erken bir sahnesinde kapının açılmaması nedeniyle ilerlemenin durduğu garip bir hata keşfedildi
- Nedeni, kapı açılırken içeride duran güvenlik görevlisinin ayak ucunun kapının hareket yoluyla çarpışması ve bunun kapının yeniden kapanıp kilitlenmesine yol açması
- Aynı çarpışma orijinal kodda da vardı, ancak 2004 x87 kayan nokta hesaplamaları ile 2013 SSE hesaplamaları arasındaki hassasiyet farkı sonucu değiştirdi
- x87 ortamında çok küçük bir dönüş ayağı hafifçe iterek çarpışmayı çözerken, SSE'de dönüş miktarı yetersiz kaldığı için kapı kapanıyor
- Bu olay, kayan nokta hassasiyeti ve derleyici farklarının gerçek oyun davranışı üzerindeki etkisini gösteren temsilî bir örnek
Half-Life 2 VR port sürecinde bulunan hata
- 2013'te Valve, Team Fortress 2'yi VR'a portlama deneyi yaparken, aynı motoru kullanan Half-Life 2 ve Portal 1 de VR'da çalışır hale geldi
- Portal 1, bakış açısı bozulması nedeniyle VR'da oynanamayacak kadar baş döndürücüydü
- Half-Life 2 ise nispeten iyi çalıştı; tekne sahneleri, kutu dizme ve manhack savaşları gibi bölümlerde VR'a özgü sürükleyicilik arttı
- Test sırasında bir geliştirici oyunu baştan sona VR'da oynarken erken tren istasyonu sahnesinde ilerlemenin imkânsız hale geldiğini fark etti
Kapının açılmama nedeninin analizi
- Normal senaryoda güvenlik görevlisi (aslında Barney) kapıyı çalıp “içeri gir” dedikten sonra, oyuncu odaya girince bir sonraki script'e geçiliyor
- Ancak hata durumunda kapı takırtıyla kapanıp kilitleniyor, güvenlik görevlisi kapıyı göstermeye devam ediyor ve oyuncu içeride mahsur kalıyor
- Orijinal Half-Life 2 kaynak kodu yeniden derlendiğinde de aynı sorun ortaya çıkınca, bu durum zamanda geriye giderek oluşmuş bir hata gibi göründü ve kafa karışıklığı yarattı
Temel neden: kayan nokta hesaplama yöntemindeki değişim
- Half-Life 2, 2004'te çıktığında x87 matematik komut setini kullanıyordu ve 32·64·80 bit hassasiyetin karışık olduğu bir yapıdaydı
- 2013 sonrası derlemelerde ise varsayılan olarak SSE komut seti kullanıldı; böylece hesaplama hassasiyeti açık biçimde 32 bit veya 64 bitle sınırlı hale geldi
- Her iki ortamda da kapı ile güvenlik görevlisinin ayak ucu çarpışıyor, ancak fizik motorundaki çok küçük hesap farkları sonucu değiştiriyor
- x87'de çarpışma sırasında güvenlik görevlisi çok hafif dönüyor, ayağı kapıdan kurtuluyor ve kapı açılıyor
- SSE'de dönüş miktarı çok az daha düşük kaldığı için ayak hâlâ temas ediyor ve kapı yeniden kapanıp kilitleniyor
Düzeltme ve çözüm
- Sorun anlaşıldıktan sonra, güvenlik görevlisinin konumu yaklaşık 1 mm geriye alınarak basitçe çözüldü
- Hata ayıklama sürecinde eski araçların kullanımını yeniden öğrenmek gibi nedenlerle ciddi zaman harcandı
- Bu örnek, hassasiyet farkları ve derleyici ayarı değişikliklerinin eski kodun davranışını değiştirebileceğini gösteriyor
Topluluk tepkisi
- Geliştiriciler, “sorun her zaman kayan nokta hassasiyetidir” diyerek duruma katıldı
- Bazıları Sonic 1·2·3 remake'lerinde çarpışma hesaplarının değiştiği örnekleri anarak benzerliğe dikkat çekti
- “Kod aynı ama derleyici farklı” dersiyle birlikte, legacy kod bakımının zorluğunu hatırlatan bir vaka olarak değerlendirildi
- Diğer geliştiriciler de Fallout 4 gibi oyunlarda NPC'lerin kapılardan geçmemesi için yapılan tasarımları bu tür sorunlarla ilişkilendirdi
- Genel olarak bunun “en ilginç hata hikâyelerinden biri” olduğu yönünde çok sayıda yorum yapıldı
1 yorum
Hacker News görüşleri
Eskiden oyun geliştirdiğim dönemde, FPU hesaplama hatası yüzünden yalnızca belirli PC'lerde assertion failure yaşandığını hatırlıyorum
Sebebi, el yazısı girişi yazılımının tüm süreçlere DLL enjekte edip FPU modunu varsayılan değere sıfırlamasıydı
Sonunda FPU ayar kodunu başlatma aşamasından event loop'a taşıyarak üçüncü taraf DLL'lerin etkisinden kaçınmıştık
Hedeflerimden biri de Valve'ı Nix kullanmaya ikna etmek
Windows desteği ilerlediği için artık daha cazip görüneceğini düşünüyorum
Böylece yalnızca kaynak kodu değil, o dönemin toolchain ve bağımlılıkları da tamamen yeniden üretilebilir hale gelir; bu tür hataların kök nedenini bulmak da çok daha kolaylaşır
Bu bana “DOOR STUCK” meme'ini hatırlattı
İlgili video
“Half-Life 2 VR beta”nın gerçekten oynanabilir olup olmadığını merak ediyorum
Eğer öyleyse neden haberim olmadı, değilse neden hâlâ olmadığını merak ediyorum
Portal VR'ı da mutlaka denemek istiyorum. İnsanlar çok mide bulandırdığını söylüyor ama ben VR motion sickness'e bağışıklıyım, o yüzden denemeye değer
Hatta uzun zaman sonra HL2'yi yeniden oynamamı sağlayacak kadar iyi yapılmış
x87'den SSE'ye geçince bazı hesaplamaların bozulması oldukça yaygın
TF2'de de aynı şey olmuştu; Linux build SSE kullandığı için mühimmat hesabı biraz farklıydı
Küçük kutudan +40 ya da +41 geliyordu ve bu, sunucunun işletim sistemine göre değişiyordu
Yeni bir sunucuya bağlanınca hangi OS olduğunu anlamaya çalışmak eğlenceliydi
Yalnızca x87'den SSE'ye geçmek bile oyunu bozuyorsa, x86→ARM dönüşümünün nasıl bu kadar iyi çalıştığı gerçekten şaşırtıcı
80 bit register kullandığı için daha yüksek hassasiyet sağlıyor ama belleğe spill edildiğinde hassasiyet kaybetmesi gibi garip davranışlar sergiliyor
Eskiden bir yazılım synthesizer debug ederken benzer bir hassasiyet hatası yaşamıştım
RC devresi simülasyonunda durumun değişmesi için değerin 0'a yeterince yaklaşması gerekiyordu ama bazı CPU'larda denormal değerler flush edilmediği için koşul sağlanmıyordu
Sonunda eşiği kabaca 0.7 ve 0.01 gibi değerlere ayarlayınca tüm platformlarda sorunsuz çalıştı
Meta bir not olarak, bir Twitter clone yapacak olsam çok paragraflı blog yazıları paylaşanları anında banlayan bir özellik eklerdim