dev-writeup-2024 / march

개발 1일 1글 스터디
2 stars 0 forks source link

[03-07] 슈퍼마리오는 어떻게 40kb로 게임을 만들었나 #15

Open neolgu opened 4 months ago

neolgu commented 4 months ago

슈퍼마리오는 어떻게 40kb로 게임을 만들었나.

들어가며

이번 편은 아무것도 하기 싫기 때문에 하는 쉬어가는 편입니다.

요즘 게임들은 최적화를 개똥으로 해놓고 유저들의 PC를 탓하는 허무맹랑한 경우가 많습니다.

(듣고 있나, 유저와 싸우는 헬다이버즈 2 직원들?)

오늘은 과거에서부터 현재까지 꾸준한 사랑을 받고 있는 슈퍼마리오 시리즈에 대한 이야기입니다.

이 게임은 무려

이젠 블루투스 이어폰도 안쓸만한 구닥다리 스펙으로 게임을 돌리고 있습니다. 어캐 이런 조선컴 스펙으로 슈퍼마리오를 만들었는지 살펴보도록 하죠?

40KB?

40kb면 어느 정도 용량일까요?

0709d19260be8f6f1bbfcba77762833e

무려 이 사진의 용량도 무려 42KB입니다. 사진보다 못한 용량을 가지고 게임을 만든다? 과연 어떻게 만들었는지 의문이 들기 시작합니다.

정확히는 소스 코드는 32KB, 그래픽 부분이 8KB였습니다.

슈퍼 마리오 게임기의 화면은 256x240의 화면 각 픽셀은 색상 값 3byte를 포함하고 있기 때문에 화면 전체를 띄우는데만 해도 180KB의 정보가 필요합니다.

그런데 그래픽 에셋이 8KB? 진짜 요즘 하남자 게임 제작자보다 상남자인 낭만의 시대의 개발자 답습니다.

타일 시스템

사실 게임을 만들떄 요소 하나하나 할 필요 없이 타일 시스템을 이용하여 배치하는 형태로 제작하면 상당히 간소화 시킬 수 있습니다.

3d5d108a0b5c6a24a22e82e7e8980573

(진짜 타일 시트는 아닙니다.)

하지만, 이 타일 시트도 128x128의 사이즈인데 48KB의 이미지 크기가 나옵니다. 어라, 그래픽 에셋이 8KB 아니였나요?

사실 원본 타일 시트는 흑백으로 4가지 색상으로 이루어졌기 때문에 1px당 2bit의 용량만 필요했습니다. 즉, 128x128x2bit = 대충 4KB의 용량이죠.

단, 여기서 이건 배경만 나온 그래픽 에셋입니다. 플레이어, 굼바, 버섯 등 우리에게 익숙한 캐릭터들은 아직 등장하지 않았죠.

캐릭터도 똑같이 타일로 만들어서 4KB의 용량이 나옵니다.

스크린샷 2024-03-07 오후 4 38 42

근데 애니메이션을 넣을려면 움직이는 모양 타일도 필요합니다.

굼바 하나가 대충 타일 4개를 사용한다 하고, 움직이는 모션이 총 3개 있다고 하면 12 개의 타일이 필요합니다.

스크린샷 2024-03-07 오후 4 39 59

단 이렇게 만들면 중복되는 부분이 생기기 때문에 중복을 재사용한다고 하면 50%를 줄일 수 있습니다.

스크린샷 2024-03-07 오후 4 41 00

여기서 더 압축하기 위해선 무슨 방법이 필요할 까요?

정답은 좌우 대칭으로 만들어버리면 됩니다.

해당 게임기는 스프라이트 뒤집기가 가능하기 떄문에 이렇게 굼바의 타일을 또 압축 시킬 수 있는 것이죠

그래서 움직이는 굼바를 만들기 위한 것은 3개의 타일이면 충분합니다.(75% 압축 달성)

스크린샷 2024-03-07 오후 4 42 33

참고로 배경은 이렇게 뒤집기나 돌리는게 되지 않았기 때문에 색상을 바꾸는 방법으로 압축했습니다.

많이 알려진 사실인 풀 숲과 구름의 모양이 동일한 이유가 여기서 나오는 것이죠

스크린샷 2024-03-07 오후 4 43 59

소스 코드 압축

이렇게 그래픽 소스를 8KB로 압축했습니다. 그럼 이제는 소스코드를 볼 차례입니다.

슈퍼 마리오 브라더스는 32개의 레벨이 있었습니다. 이 소스 코드 중 대부분을 차지하는게 이런 레벨 디자인 입니다.

이런 스테이지의 소스 코드는 어떤 위치에 무슨 블록을 배치 할지를 적어 두었는데

스크린샷 2024-03-07 오후 4 46 54

만약 이 블록 위치가 타일 위치가 아닌 픽셀 위치였다면 0~255까지 값을 저장해야 하기 때문에 2byte가 하나당 필요했을 것입니다.

하지만, 픽셀 위치가 아닌 타일 위치를 기록했기 떄문에 16x16 좌표로 표현 가능합니다. 즉 1byte 내로 표현이 가능해졌다~ 이런 말이죠.

성능 최적화

이런 구닥다리 게임기는 하드웨어적 한계가 있습니다.

해당 게임기는 한줄에 최대 8개의 사물 혹은 캐릭터 타일만 넣을 수 있었습니다. (9 개가 넘어가면 사라져버립니다.)

그런데 우리는 게임을 할때 마리오도 있고 굼바도 있고 쿠파도 있고 여러가지 나오는 게임을 즐겼습니다.

과연 이건 어떻게 해결했을까요?

정답은 플리커링입니다.

빠르게 타일을 껏다 켯다 반복하면서 8개의 최대치로 빠르게 바꿔 표현했습니다.

그래서 옛날 게임을 하다보면 빠르게 번쩍 거리는 게임들이 있습니다. 다 이 방법을 이용해 최대 표현 가능한 타일을 넘긴 것 입니다.

플리커링이란?

플리커(flicker)는 간단히 설명하자면, 빛을 내는 LED 라이트나 전자기기 화면 속 밝기가 일정하지 않고 깜빡이며 화면이 떨리는 증상을 말한다. 하지만 플리커는 눈으로 쉽게 감지가 되지 않는데 이는 그 떨리는 속도가 매우 빠르기 때문이다. 이러한 플리커 현상은 또 다른 말로 플리커링(flickering)이라고 부르기도 하는데 플리커와 플리커링 둘 모두 동일한 현상을 뜻한다.

효과음

자 이렇게 그래픽과 소스코드를 보았습니다. 하지만 음악이 있어야 진정한 게임의 완성이겠죠?

슈퍼마리오에서 스테이지를 클리어하는 나오는 익숙한 효과음

스테이지 클리어

그리고 버섯을 먹을 때 나는 효과음

버섯

여기서 숨겨진 사실은

스테이지 클리어 효과음을 "배속"을 주면 동일한 소리라는 것을 알 수 있습니다.

또 다른 것들은

  1. 적에게 닿을 때 줄어드는 소리 = 파이프 안으로 들어가는 소리
  2. 물 속에서 물장구치는 소리 = 굼바가 죽는 소리

요정도가 있겠네요

이런거 하나하나 모아 40KB로 게임을 만든 것입니다.

마치며

낭만의 시대, 게임 개발자들의 최적화 아트의 총집편이 슈퍼마리오라고 생각합니다. (혹은 NASA의 우주선 발사 소스코드라던지...)

요즘 것들은 렘 몰랑~ 높은 램써~ / 그래픽 로드? 몰랑 4090 써~

이런 놈들이 많아서 대가리를 머지소트 해버리고 싶습니다.

슈퍼마리오의 다음 시리즈였던 슈퍼마리오 64는 무려 8MB로 슈퍼마리오 64를 4초간 캡쳐한 동영상보다 용량이 작다고 합니다...

다들 컴 성능 좋아졌다고 막 쓰지말고 최적화를 한 번 해보도록 합시다.

출처

코딩애플 - 슈퍼마리오 편

snaag commented 4 months ago

오오........... 이 짤이 생각나네요 image

Longseabear commented 3 months ago

생각보다 자세히 조사했네; 재밌게 봤습니다

fxzyk commented 3 months ago

죄송함다 !! 빡세게 최적화하겠슴다!! 😣