- Half-Life 2의 초반 장면에서 문이 열리지 않아 진행이 멈추는 이상한 버그가 발견됨
- 원인은 문이 열릴 때 내부에 서 있는 경비병의 발끝이 문 경로와 충돌하면서 문이 다시 닫히고 잠기는 현상
- 원본 코드에서도 동일한 충돌이 존재했지만, 2004년 x87 부동소수점 연산과 2013년 SSE 연산의 정밀도 차이로 결과가 달라짐
- x87 환경에서는 미세한 회전으로 발이 살짝 밀려 충돌이 해소되지만, SSE에서는 회전량이 부족해 문이 닫히는 결과 발생
- 이 사례는 부동소수점 정밀도와 컴파일러 차이가 실제 게임 동작에 미치는 영향을 보여주는 대표적 사례
Half-Life 2 VR 포팅 과정에서 발견된 버그
- 2013년 Valve에서 Team Fortress 2를 VR로 포팅하는 실험 중, 같은 엔진을 사용하는 Half-Life 2와 Portal 1도 VR에서 작동하게 됨
- Portal 1은 시점 왜곡으로 인해 VR에서 플레이가 불가능할 정도로 어지러웠음
- Half-Life 2는 비교적 잘 작동했으며, 보트 장면과 상자 쌓기, 맨핵(manhack) 전투 등에서 VR 특유의 몰입감이 향상됨
- 테스트 중 개발자가 게임을 처음부터 끝까지 VR로 플레이하다가 초반 열차역 장면에서 진행 불가 상태를 발견
문이 열리지 않는 원인 분석
- 원래 시나리오에서는 경비병(사실은 Barney)이 문을 두드리고 “들어가라”고 말한 뒤, 플레이어가 방에 들어가면 다음 스크립트로 진행됨
- 그러나 버그 상황에서는 문이 덜컥거리다 잠기며 완전히 닫혀버림, 경비병은 계속 문을 가리키고 플레이어는 갇히는 상태
- 원본 Half-Life 2 소스코드를 다시 빌드해도 동일한 문제가 발생해, 시간을 거슬러 생긴 버그처럼 보이는 현상으로 혼란이 발생
근본 원인: 부동소수점 연산 방식의 변화
- 2004년 출시 당시 Half-Life 2는 x87 수학 명령어 세트를 사용했으며, 32·64·80비트 정밀도가 혼재된 구조였음
- 2013년 이후 빌드에서는 SSE 명령어 세트가 기본으로 사용되어, 32비트 또는 64비트로 명확히 제한된 연산 정밀도 적용
- 두 환경 모두에서 문과 경비병의 발끝이 충돌하지만, 물리엔진의 미세한 계산 차이로 결과가 달라짐
- x87에서는 충돌 시 경비병이 아주 약간 회전해 발이 문에서 벗어나 문이 열림
- SSE에서는 회전량이 미세하게 줄어 발이 여전히 닿아 문이 다시 닫히고 잠김
수정 및 해결
- 문제를 파악한 후, 경비병의 위치를 약 1mm 뒤로 이동시키는 간단한 수정으로 해결
- 디버깅 과정에서는 오래된 도구 사용법을 다시 익히는 등 상당한 시간이 소요됨
- 이 사례는 정밀도 차이와 컴파일러 설정 변화가 과거 코드의 동작을 바꿀 수 있음을 보여줌
커뮤니티 반응
- 개발자들은 “항상 문제는 부동소수점 정밀도 때문”이라며 공감
- 일부는 Sonic 1·2·3 리메이크의 충돌 계산 변화 사례를 언급하며 유사성을 지적
- “코드는 같지만 컴파일러는 다르다”는 교훈과 함께, 레거시 코드 유지의 어려움을 상기시키는 사례로 평가됨
- 다른 개발자들은 Fallout 4 등에서 NPC가 문을 통과하지 않도록 설계한 이유를 이와 같은 문제로 연결해 언급
- 전체적으로 “가장 흥미로운 버그 스토리 중 하나”라는 반응이 다수였음