정상 속도인데도 끊기던 화면
닌텐도 DS의 3D 게임은 정상 속도로 실행되는데도 화면이 끊겼습니다. 1.5.0에서는 각 프레임을 표시할 시각을 정해 화면이 고르게 갱신되도록 했습니다.
닌텐도 DS의 3D 게임을 할 때 게임은 정상 속도로 실행되는데 화면만 끊기는 경우가 있었습니다. 게임이 프레임을 만드는 속도에는 문제가 없었지만, 화면에 표시되지 않는 프레임이 전체의 3분의 1가량이었습니다.
원인을 찾으려고 ‘프레임 표시’ 기능을 만들었습니다. 첫째 줄은 게임이 만든 초당 프레임 수와 원래 게임기 대비 실행 속도를 보여 줍니다. 둘째 줄에는 화면에 새로 표시된 초당 프레임 수와 화면 갱신 횟수가 나옵니다. 첫째 줄의 실행 속도는 정상인데 둘째 줄의 프레임 수만 낮다면 화면 표시 쪽에 문제가 있습니다. 일시정지 메뉴의 화면 구역에서 켜고 끌 수 있습니다.
DS 게임은 3D 화면을 1초에 30번 그리는 경우가 많습니다. 3D를 그리는 프레임은 계산할 일이 많고, 그다음 프레임은 적어서 두 프레임의 계산이 거의 동시에 끝나기도 합니다. 이전에는 화면을 갱신할 때 가장 최근에 완성된 프레임만 가져왔습니다. 두 프레임이 잇달아 완성되면 앞의 프레임은 표시하지 못한 채 건너뛰었습니다.
이제는 각 프레임을 표시할 시각을 정합니다. 게임의 실행 주기로 계산한 원래 표시 시각에 짧은 대기 시간을 더합니다. 완성된 프레임은 최대 네 장까지 보관하고, 화면을 갱신할 때 표시할 시각이 된 프레임 중 가장 최신 것을 보여 줍니다. 거의 동시에 완성된 두 프레임도 각자의 표시 시각에 맞춰 한 장씩 나옵니다.
대기 시간은 처음에 대부분의 프레임이 완성되는 시간을 기준으로 삼았다가, 최근 2초 동안 가장 늦게 완성된 프레임에 맞추도록 바꿨습니다. 하지만 느린 프레임이 그 범위에서 빠질 때 대기 시간이 줄어들어, 다른 프레임을 건너뛰는 문제가 생겼습니다. 이제는 프레임이 정해 둔 대기 시간보다 늦게 완성되면 대기 시간을 바로 늘립니다. 늘어난 대기 시간은 그대로 유지합니다. 대기 시간을 한 프레임만큼 줄여도 모든 프레임을 제때 표시할 수 있는 상태가 30초 동안 이어져야 그만큼 줄입니다. 대기 시간은 최대 두 프레임입니다. 화면 표시가 조금 늦어지더라도 끊김을 줄이는 쪽을 택했습니다.
iOS와 Android 모두 이 방식으로 화면에 표시할 프레임을 고릅니다. 게임기의 실행 주기와 화면 갱신 주기의 차이가 1.2% 이내면 게임의 실행 속도를 화면 갱신 주기에 맞추고, 소리의 재생 속도도 같은 비율로 조절합니다. iOS에서는 DS의 3D 화면을 게임 실행과 별도의 스레드에서 그리도록 했습니다. DS 코어를 빌드할 때 링크 단계 최적화(LTO)를 켜는 변경도 함께 했습니다.
실제 기기에서는 iPhone 한 대로만 확인했습니다. Android 기기나 다른 게임에서 화면 끊김이 얼마나 줄었는지는 아직 측정하지 않았습니다.
함께 읽을 개발 이야기
- 개발 이야기v1.3.0클로즈 베타 테스트
런어헤드로 버튼 반응 앞당기기
게임은 버튼 입력을 읽은 뒤 한 프레임 이상 지나야 반응을 화면에 보여 줍니다. 런어헤드는 그만큼 미리 진행해 반응을 앞당깁니다. 대신 계산량이 늘어 배터리를 더 씁니다.
- 개발 이야기v1.2.0클로즈 베타 테스트
일시정지 화면의 반복 작업 줄이기
게임을 일시정지해도 화면을 그리는 작업은 반복될 수 있습니다. 1.2.0에서는 새 영상이 들어오거나 표시 설정이 바뀔 때 다시 그리고, 설정을 저장하기 전에 미리 시험할 수 있게 했습니다.