게임과 버그: 포탈

글 목록

2025. 02. 10.

2019년에 게임회사를 다니면서는 유저들이 제보한 버그를 고치는 일을 했었다. 여러 버그들 중 두 유저가 동시에 포탈을 타고 다른 지역으로 이동했더니 갑자기 상대 캐릭터가 사라지고 체력바만 허공에 떠다니는 현상이 발견되어 이를 조사했던 것이 아직도 기억난다. 어떻게 이런 일이 일어났는가? 이를 이해하기 위해서는 게임의 작동 원리 및 각종 구현 테크닉들에 대한 이해가 필요하다.

우선 포탈이 무엇인지 알아야 한다. 포탈이란, 쉽게 말해서, 멀리 떨어진 두 공간 사이를 순식간에 오갈 수 있도록 해주는 관문 형태의 장치다. 이 '순식간'이라는 시간을 어떻게 정의하냐에 따라 현실 세계에서도 비슷한 장치를 떠올려볼 수 있는데, 예를 들어 엘리베이터도 탑승 후 몇 초 정도 기다리면 낮은 곳에서 높은 곳으로, 혹은 그 반대로 바로 이동할 수 있다는 측면에서 일종의 포탈 같은 역할을 한다고 볼 수 있다. 다만 게임의 포탈과 현실의 엘리베이터 사이에는 아주 큰 차이가 하나 있는데, 바로 '이 장치를 통해 이동하는 중에 이동의 주체가 어디에 존재하냐'는 것.

신체를 이루는 원자들을 그대로 복사해서 다른 공간에 내 신체를 옮기는 식의 공상과학적인 접근을 하지 않는 이상, 현실 세계에서의 내 신체가 한 지점에서 다른 지점으로 이동하기 위해서는 두 점을 잇는 이동 경로 상에 항상 내 신체가 존재한다. 그렇다면 게임에서는 어떨까? 내가 유지보수 하던 게임에서는 공간 속 신체의 연속성과 같은 개념이 존재하지 않았다. 게임에서 일어나는 모든 일이 정지 화면(혹은, 프레임)들의 연속으로 이루어지는 것이라 하면, 한 프레임에서 A위치에 있던 내 캐릭터가 포탈을 타고 이동하면 바로 다음 프레임에서는 B위치에 있는 것이다. A와 B 사이의 어느 공간에도 캐릭터가 존재하지 않았을 뿐만 아니라, 캐릭터의 모든 행동들이 프레임이라는 단위 위에서 설명된다는 것이 아주 중요하다.

그리고 이 프레임은 내가 게임을 플레이하고 있는 컴퓨터에서 계산된다. 정확히는, 게임을 이루는 각종 지형과 장애물, 몬스터, 플레이어의 정보를 종합해서 이를 시각적 이미지로 만들어내는 작업이 내 컴퓨터에서 이루어지고, 각종 지형 및 장애물 정보는 내 컴퓨터에 저장되어 있는 정보에서 끌어와서 쓰고 몬스터와 다른 플레이어의 정보는 게임 회사에서 관리하는 서버에서 정보를 받아와서 사용하는 식으로 작동한다. 물론 다른 플레이어의 화면에도 내 캐릭터가 나와야 한다. 이를 위해서 내가 게임을 하는 중에 내 컴퓨터는 게임 회사 서버로 내 캐릭터의 위치, 사용하고 있는 스킬, 아이템 등의 정보를 계속해서 보내고, 다른 플레이어의 컴퓨터에서는 이 정보를 받아서 화면을 만드는 데에 활용한다.

프레임을 만드는 데에 있어 신경써야 하는 것 중 하나는 프레임을 만드는 데에 최대한 시간이 짧게 소요되어야 한다는 것이다. 1초에 60프레임 정도를 만들어낸다면 내가 플레이하는 게임이 부드럽게 구동되는 것처럼 느껴지겠지만, 1초에 10프레임 정도씩밖에 계산할 수 없다면 화면이 뚝뚝 끊어지는 것처럼 보일 것이다. 앞서 말했듯이 프레임 하나를 계산하기 위해서는 게임에 있는 각종 지형과 플레이어 등의 객체의 정보가 필요하다. 이 정보에는 몬스터의 종류와 체력 같은 정보도 있고, 몬스터나 플레이어의 3D 모델링 정보도 있다. 이 중 3D 모델링 정보는 렌더 엔진을 거쳐 시각적으로 보이는 정보로 계산되는데, 여기에 시간이 많이 들어가므로 불필요한 3D 정보를 프레임 계산에서 최대한 배제하는 것이 중요하다고 할 수 있겠다.

그래서 내가 유지보수하던 게임에서는 내 캐릭터 주변에 있는 요소들의 정보만 프레임 계산에 사용하도록 하는 기법을 활용했다. 매 프레임을 계산할때마다 내 캐릭터 주변에 있는 요소들에 변동이 있는지 확인한 뒤 업데이트하고, 이 요소들에 대해서만 프레임 계산에 고려하는 식이다. 내 캐릭터와 아주 멀리 떨어진 나무는 화면에 보일 필요도 없고 내 화면에 보이는 요소들에 영향을 주지 않으므로 내 컴퓨터는 나무의 정보를 모른 채로 프레임을 계산한다. 나중에 내 캐릭터가 나무 근처에 가면 그제서야 나무의 정보를 받아와서 프레임 계산에 쓸 준비를 한다. 비슷하게, 내 캐릭터가 이동하면서 원래는 근처에 있었던 몬스터와 거리가 멀어지면 내 컴퓨터는 몬스터의 정보를 지워버린다. 내 컴퓨터 입장에서는 몬스터의 정보를 프레임 계산에 고려할 필요가 없으니, 몬스터의 존재 자체를 소멸시켜버리는 것이다.

그럼 다시 두 플레이어가 동시에 포탈을 탔더니 같이 포탈을 타고 넘어온 다른 플레이어의 캐릭터가 사라지고 체력바만 남은 버그로 돌아와보자. 이 버그는 다음과 같은 방식으로 발생했다. 먼저, 내 캐릭터가 포탈을 타고 먼 곳으로 이동했다. 그러자 내 컴퓨터는 상대 플레이어가 내 주변에 없다고 판단하여 플레이어의 3D 정보를 지워버렸다. 그리고 바로 다음 프레임에서 캐릭터의 고유 정보까지 지웠어야 했는데, 하필 바로 다음 프레임에서 상대 플레이어가 포탈을 타고 내 근처로 와버렸다. 그 바람에 상대 캐릭터가 내 주변에 있는 것으로 판정되어 게임 엔진은 고유 정보를 지우지 않는다. 즉, 게임 엔진 입장에서는 상대 캐릭터가 쭉 내 주변에 있어왔던 것으로 판단하여, 상대 캐릭터의 3D 정보를 업데이트하지 않고 지워진 상태 그대로 내버려둔다. 캐릭터의 체력바는 캐릭터의 고유 정보를 활용하여 표시한 것이므로, 나에게는 상대 플레이어의 캐릭터는 보이지 않고 체력바만 떠다니는 것처럼 보인다.

현실에서는 내 주변에 있는 상대가 내 시야에서 사라진다고 소멸시키지도 않고, 몇 ms 시간 간격 내에 발생한 일로 어떤 드라마틱한 일이 일어나는 것에 대해 신경쓸 일도 보통이면 없다. 가상의 경험과 현실의 경험을 연결짓겠다고 생각한다면, 현실의 규칙과 가상의 규칙이 만나는 지점에 대해 신경을 써야 할지도 모른다.

글 목록