게임과 버그: 벽 뚫기
2025. 02. 15.
게임회사에서 일하던 중 한 번은 어떤 유저가 아직 공개되지 않은 신규 맵에 들어간 것을 잡은 적이 있었다. 해당 맵으로 이동할 수 있는 포탈이 아직 구현되지 않은 상황이었으니 이 외딴 곳에 덩그러니 놓여있는 필드로 가려면 날아서 가는 것 말고는 방법이 없었다. 하지만 이 게임에서는 날아가는 것은 커녕 점프도 할 수 없었던 상황. 도대체 유저는 어떻게 이동이 막혀있는 지역에 갈 수 있었던 걸까?
나중에 밝혀진 바에 의하면, 이 유저는 기존 맵에서 이동이 불가능하도록 막힌 부분을 '뚫고' 지나간 것으로 확인되었다. 뚫고 지나간다니, 이게 무슨 말일까? 저번의 포탈 버그와 비슷하게 이를 이해하기 위해서는 게임으로 구현된 공간 대한 이해가 필요한데, 특히 공간 안에서의 이동과 이를 제한하는 테크닉을 잘 알아야 한다.
게임 공간에 대한 이야기를 하기 전에 먼저 현실 공간을 떠올려보자. 어떤 사람이 방 안에 있다. 방은 어떻게 생겨도 상관 없고, 최소 한 면에 벽이 있기만 하면 된다. 그리고 이 사람이 벽 너머에 있는 공간으로 가고 싶다. 그래서 이 사람이 벽을 향해 걸어간다면, 당연하게도, 벽 너머의 공간에 도달하기 전에 벽에 부딪치고 말 것이다. 왜 벽에 부딪친 걸까? 왜냐하면 이 사람이 가려고 한 공간에 이미 벽이 자리잡고 있었고, 벽이 충분히 잘 고정되어 있어서 사람이 벽이 놓인 공간으로 이동하기 위해 벽에 힘을 가했을때 밀려나지 않고 그 자리에 버티고 있었기 때문이다. 그러니까, 부딪친다, 혹은, 충돌한다는 개념이 존재하기 위해서는 한 공간에 여러 물체가 동시에 존재할 수 없다는 전제가 깔려야 한다.
게임 공간에서는 어떨까? 흥미롭게도 가상의 공간에서는 별도의 규칙을 설정하지 않는다면 같은 공간에 여러 물체가 동시에 존재하는 것이 가능하다. 좀 더 구체적으로는, 두 물체 사이에 어떤 상호작용이 일어날 수 있을지 정의하지 않으면 이 둘은 완전히 다른 세계에 존재하는 것처럼 서로에게 어떤 영향도 끼치지 못한다. 그렇기 때문에 게임에서 한 캐릭터가 벽 너머로 이동하지 못하게 막기 위해서는 별도의 장치를 해야 한다. 예를 들어, 어떤 물체가 다른 물체가 있는 자리로 가려고 하면 두 물체가 점유하는 공간이 겹치는지, 즉, 충돌하는지 판정해서 움직임을 막는 식이다. 이전 글에서 프레임에 대해 설명했는데 여기에서도 프레임 개념이 유용하다. 현재 프레임에서는 사람과 벽이 안 겹쳐있었는데 그 다음 프레임을 계산하려고 하니 사람이 움직여서 벽과 겹칠 경우, 사람의 위치를 조정해서 최종 도달한 위치가 벽과 겹치지 않도록 하는 것이 충돌 방지를 무난하게 구현할 수 있는 방법 중 하나일 것이다.
문제는 이 충돌판정을 구체적으로 어떻게 구현할 것이냐에 있다. 버그가 발생한 게임은 3D 게임이었으니 두 3D 도형이 겹치는지 판별하는 알고리즘을 짜면 될 것 같지만, 3D 도형의 충돌 판정에는 많은 계산량이 필요하므로 실시간으로 프레임을 계산해내야 하는 상황에서는 적합하지 않다. 그렇다면 이 게임에서는 어차피 점프와 날아가는 것이 지원되지 않으니 3D 도형을 바닥으로 프로젝션 하여 나온 2D 도형들 사이의 충돌 판정을 하는 것도 괜찮아보인다. 그런데 두 2D 도형 사이의 충돌 판정을 나이브하게 구현하려고 하면, 예를 들어, m개의 점으로 이루어진 다각형의 모든 점들에 대해 n개의 점으로 이루어진 다각형 내부에 들어가는지 보려고 하면, 최악의 경우 m * n 에 비례하는 계산량이 필요하므로 캐릭터가 복잡하게 생겼을 경우 프레임 계산에 많은 시간이 소요될 것이다(뿐만 아니라 이 방법은 잘못된 충돌 판정법이다. 육망성을 이루는 두 삼각형은 서로 겹쳐있지만 두 도형을 이루는 점들은 모두 다른 도형 바깥에 있다.). 그래서 두 도형이 겹치는지 아주 정확히 판별할 필요가 없다면 두 도형을 감싸는 직사각형으로 충돌 판정을 하는 경우가 많다. 이에 대해서는 AABB(axis aligned bounding box), OBB(oriented bounding box)등의 키워드로 검색하면 정보가 많이 나온다. 이렇게 하면 게임 플레이에는 큰 영향을 주지 않으면서 필요한 연산량을 많이 줄이는 것이 가능하다.
게임을 유지보수한지 시간이 오래 지나서 기억이 가물가물하긴 하지만, 내가 일하던 곳에서는 여기서 한 번 더 최적화를 했던것 같다. 만약 내 캐릭터가 앞으로 이동하고 있다면, 캐릭터의 앞에 있는 어떤 점 하나가 다른 물체와 충돌하는지 판별하는 것으로 연산량을 한 번 더 줄이는 것이 가능하지 않을까? 이 최적화는 꽤 잘 작동했던 것으로 보인다. 어떤 아주 창의적인 유저가 나타나기 전까지는. 여기부터는 버그의 내용이 잘 기억나지 않아 약간의 추측이 포함된다. 한 창의적인 유저는 이동 속도를 감소시키는 효과가 붙어있는 장비를 착용하고 물약을 먹는 것으로 이동 속도를 마이너스로 바꾸는 것이 가능한 것을 발견해낸다. 그러니까, 캐릭터를 앞으로 이동하도록 조작하는데, 실제 이동 방향은 뒤가 되는 것이다. 그러면 캐릭터의 충돌 판정점은 캐릭터 앞에 있는데, 실제로는 캐릭터가 뒤로 움직이고 있으니 캐릭터의 등이 다른 물체를 통과할 수 있게 된다. 이 유저는 맵을 돌아다니던 중 이 현상을 우연히 발견했을 지도 모른다. 그리고 맵 끝에 있는 벽과 겹쳐있는 상태에서 장비를 갈아입어서 다시 이동 속도를 플러스로 바꾼 뒤 움직이려고 시도하니 벽 뒤 공간 어딘가로 튕겨나갔거나, 혹은 아무 장애물이 없어서 자유롭게 벽 뒤 공간에서 이동이 가능했을 수도 있겠다. 이제 유저의 앞에는 그간 돌아다닐 수 없었던 미지의 세계가 열렸다. 혹시 개발자가 숨겨놓은 맵이 있는지 구석구석 돌아다녀볼 수 있는 것이다.