게임을 즐기는 환경은 사람마다 제각각입니다. 어떤 프로그래머는 고사양 PC를 쓰고 누군가는 조금 느린 노트북을 사용합니다. 하지만 하드웨어 성능 차이 때문에 게임 속도가 달라지면 곤란합니다.
빠른 컴퓨터에서 게임이 2배로 빨리 진행된다면 공평하지 않겠죠. 반대로 느린 컴퓨터라고 해서 슬로 모션처럼 보여서도 안 됩니다. 그래서 우리는 델타 타임(Delta Time)이라는 중요한 개념을 활용합니다.
모든 컴퓨터에서 같은 속도를 유지하는 방법
이 문제를 해결하기 위해 프로그래머는 프레임 사이의 시간을 측정합니다. 즉 화면이 한 번 그려지고 다음 화면이 그려질 때까지 시간이 얼마나 흘렀는지를 봅니다. 이 시간 간격을 기준으로 게임 로직을 업데이트하죠.
이렇게 하면 프레임 레이트가 높든 낮든 일정한 속도를 보장할 수 있습니다. 성능이 다른 컴퓨터에서도 캐릭터는 똑같은 속도로 움직이게 됩니다. 이것이 바로 델타 타임을 사용하는 가장 큰 이유입니다.
시간을 기준으로 계산하는 원리
원리는 생각보다 어렵지 않습니다. 예를 들어 캐릭터가 초당 5미터를 이동한다고 가정해 봅시다. 이때 단순히 5를 더하는 것이 아니라 속도에 델타 타임을 곱해서 더해줍니다.

그러면 프레임이 많으면 조금씩 여러 번 더해지고 프레임이 적으면 한 번에 많이 더해집니다. 결과적으로 1초가 지났을 때 이동한 거리는 똑같아지죠. 처음엔 낯설 수 있지만 현대 게임에서는 표준처럼 쓰이는 방식입니다.
완벽해 보이는 방식의 치명적인 약점
하지만 이 방식에도 주의해야 할 부분이 있습니다. 게임을 하다 보면 가끔 화면이 멈칫하거나 뚝 끊기는 경험을 해보셨을 겁니다. 우리는 이것을 프레임 스파이크(Frame Spike)라고 부릅니다.
보통 다음 프레임 계산에는 지난 프레임에서 잰 시간을 사용합니다. 그런데 갑자기 렉이 걸려 한 프레임이 평소보다 훨씬 오래 걸렸다면 어떨까요? 당연히 측정된 델타 타임 값이 비정상적으로 커지게 됩니다.
갑자기 커진 시간 값이 만드는 오류
이렇게 커진 값이 그대로 다음 계산에 들어가면 문제가 생깁니다. 물리 엔진이나 이동 로직은 보통 아주 짧은 시간을 전제로 설계되어 있기 때문입니다. 갑자기 큰 시간이 입력되면 캐릭터가 벽을 뚫고 지나가기도 합니다.
혹은 충돌해야 할 물체를 그대로 통과해 버리는 일도 생깁니다. 촘촘하게 검사해야 할 구간을 한 번에 건너뛰기 때문에 벌어지는 현상이죠. 물리 시뮬레이션이 불안정해지는 대표적인 원인 중 하나입니다.
렉이 더 심한 렉을 부르는 악순환
더 큰 문제는 상황이 점점 나빠질 수 있다는 점입니다. 델타 타임이 커지면 물리 엔진은 그만큼 많은 변화를 처리하기 위해 복잡한 계산을 수행합니다. 그러면 연산량이 늘어나 다음 프레임은 더 느려지게 되죠.
프레임이 느려지니 델타 타임은 또다시 커집니다. 그러면 물리 엔진은 더 많은 부하를 견뎌야 하는 상황이 반복됩니다. 한번 발생한 끊김 현상이 계속 이어지는 이유가 바로 여기에 있습니다.
안정적인 게임을 위한 엔진의 대처
그래서 실제 상용 엔진들은 안전장치를 둡니다. 델타 타임 값이 아무리 커져도 일정 수치 이상은 넘지 못하게 상한선을 두는 식입니다. 혹은 물리 연산만 고정된 시간 간격으로 실행하기도 하죠.
델타 타임이 갑자기 튀는 상황은 언제든 발생할 수 있습니다. 중요한 것은 그 상황을 어떻게 안전하게 처리하느냐입니다. 이런 예외 처리까지 꼼꼼하게 챙기는 것이 프로그래머의 역할입니다.