# 하프라이프 2의 시간여행하는 문 버그

> Clean Markdown view of GeekNews topic #24561. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24561](https://news.hada.io/topic?id=24561)
- GeekNews Markdown: [https://news.hada.io/topic/24561.md](https://news.hada.io/topic/24561.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-11-24T06:34:24+09:00
- Updated: 2025-11-24T06:34:24+09:00
- Original source: [mastodon.gamedev.place](https://mastodon.gamedev.place/@TomF/115589875974658415)
- Points: 1
- Comments: 1

## Topic Body

- **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가 문을 통과하지 않도록 설계한 이유를 이와 같은 문제로 연결해 언급  
- 전체적으로 “가장 흥미로운 버그 스토리 중 하나”라는 반응이 다수였음

## Comments



### Comment 46708

- Author: neo
- Created: 2025-11-24T06:34:25+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=46009962) 
- 예전에 게임 개발을 하던 시절, **FPU 계산 오류**로 특정 PC에서만 어설션 실패가 발생했던 기억이 있음  
  원인은 필기 입력 소프트웨어가 모든 프로세스에 DLL을 주입하면서 FPU 모드를 기본값으로 **리셋**하는 것이었음  
  결국 FPU 설정 코드를 초기화 단계에서 이벤트 루프로 옮겨, 서드파티 DLL이 끼치는 영향을 회피했음
  - 멋진 추적이었음. 전역 FPU 상태는 정말 많은 **두통거리**를 만들어왔음

- 내 목표 중 하나는 **Valve가 Nix를 사용**하게 만드는 것임  
  Windows 지원이 진행 중이라 더 매력적으로 보일 거라 생각함  
  이렇게 되면 원본 소스뿐 아니라 당시의 **툴체인과 의존성**까지 완전히 재현할 수 있게 되어, 이런 버그의 근본 원인도 훨씬 쉽게 찾을 수 있을 것 같음

- “DOOR STUCK” 밈이 떠오름  
  [관련 영상](https://www.youtube.com/watch?v=dBIh06_bmq0)

- “Half-Life 2 VR 베타”가 실제로 플레이 가능한 것인지 궁금함  
  만약 가능하다면 왜 몰랐는지, 아니라면 왜 아직 안 되는지 의문임  
  **Portal VR**도 꼭 해보고 싶음. 멀미가 심하다고들 하지만 나는 VR 멀미에 면역이라 시도해볼 만함
  - 베타는 모르겠지만, 지금 바로 즐길 수 있는 훌륭한 **HL2 VR 컨버전 모드**가 있음  
    오랜만에 HL2를 다시 하게 만들 정도로 완성도가 높음
  - **Portal 2 VR 모드**도 있음. 끝까지 플레이했는데 의외로 편안하게 즐길 수 있었음

- x87에서 SSE로 전환할 때 일부 계산이 깨지는 건 흔한 일임  
  **TF2**에서도 같은 일이 있었는데, Linux 빌드에서는 SSE를 사용해 탄약 계산이 약간 달랐음
  - 탄약 계산에 **float**을 썼다는 게 놀라움
  - 실제로 눈에 띄는 차이는 엔지니어의 **metal 수치** 정도였음  
    작은 상자에서 +40 또는 +41을 주는데, 서버 OS에 따라 달랐음  
    새 서버에 접속할 때마다 어떤 OS인지 확인하는 재미가 있었음

- x87에서 SSE로만 바꿔도 게임이 깨지는데, **x86→ARM 변환**이 어떻게 그렇게 잘 되는지 신기함
  - x87 FPU만이 유일하게 **특이한 부동소수점 유닛**임  
    80비트 레지스터를 써서 정밀도가 높지만, 메모리에 spill될 때 정밀도를 잃는 등 이상한 동작을 보임
  - 정밀도 차이로 인해 수치가 아주 미세하게 달라지고, 그게 **문 충돌** 같은 문제로 이어지는 경우가 있음  
    예전에 소프트웨어 신시사이저를 디버깅할 때도 비슷한 **정밀도 버그**를 겪었음  
    RC 회로 시뮬레이션이 0에 근접해야 상태가 바뀌는데, 특정 CPU에서는 denormal 값이 플러시되지 않아 조건을 만족하지 못했음  
    결국 0.7과 0.01 정도로 대충 임계값을 조정하니 모든 플랫폼에서 잘 동작했음

- 메타 이야기로, **트위터 클론**을 만들 건데 여러 단락으로 블로깅하면 바로 밴시키는 기능을 넣을 생각임  
  - 해당 스레드를 한 페이지로 펼쳐주는 [링크](https://mastoreader.io/?url=https%3A%2F%2Fmastodon.gamedev.place%2F%40TomF%2F115589875974658415)를 공유함
  - 이런 포스팅 옵션이 없다고 해서 스레드가 사라지는 건 아니라는 의견임
  - 반대로, 최소 두 단락 이상 써야 하고 **LLM이 내용 검증**을 하는 플랫폼을 만들자는 제안도 있었음
