포켓몬스터 블루의 MissingNo. 글리치에서 배우는 공감

Rocky Mountain Ruby 2025 - Learning Empathy From Pokémon Blue by Tess Griffin

작성자
jeff
발행일
2025년 10월 23일

핵심 요약

  • 1 포켓몬스터 블루의 MissingNo. 글리치는 게임보이의 엄격한 메모리 및 코드 크기 제약 속에서 여러 개의 작은 버그가 예상치 못하게 상호작용한 결과입니다.
  • 2 이 글리치는 개발자들이 제한된 리소스 하에서 최적화를 위해 코드 재사용 및 바운드 체크 생략 등의 결정을 내렸음을 보여주며, 이는 현대 개발 환경과의 중대한 차이를 시사합니다.
  • 3 과거 개발 환경의 어려움을 이해하고, 현대 프로그래밍 언어와 도구들이 제공하는 추상화 및 안전 기능의 중요성을 깨닫는 계기가 됩니다.

도입

본 발표는 포켓몬스터 블루(Pokemon Blue) 게임에서 발견된 유명한 'MissingNo.' 글리치를 통해 개발 과정에서의 공감 능력 함양을 주제로 합니다. 1996년 출시된 포켓몬스터 레드 및 그린 버전은 소규모 팀이 작은 예산으로 개발했으며, 이 게임은 예상치를 훨씬 뛰어넘는 인기를 얻었습니다. 이후 출시된 업데이트 버전과 전 세계 출시 과정에서, 개발자들은 극심한 시간과 자원 제약 속에서 작업해야 했습니다. 이 글리치는 단순한 버그가 아니라, 당시의 개발 환경과 제약 사항을 이해하는 중요한 사례로 제시됩니다.

MissingNo. 글리치는 단일한 버그가 아닌, 여러 작은 코드 특성들이 예상치 못하게 결합되어 발생했습니다. 이는 주로 게임보이의 극심한 메모리 제약과 어셈블리 언어 사용에서 비롯되었습니다.

MissingNo. 글리치 발생 원인

1. 해안 타일의 포켓몬 조우 로직

  • 문제점: 야생 포켓몬 조우 여부를 판단할 때는 플레이어 캐릭터의 오른쪽 아래 서브타일(물)을 참조하는 반면, 조우할 포켓몬의 종류(물/풀)를 결정할 때는 왼쪽 아래 서브타일(육지)을 참조합니다.

  • 결과: 플레이어가 해안선을 따라 이동할 때, 물 위에 있지만 육지 포켓몬(풀 타입)을 만날 수 있는 상황이 발생합니다.

2. 지역 전환 시 조우 테이블 유지

  • 문제점: 새로운 지역으로 이동할 때, 해당 지역의 풀 포켓몬 조우율이 0보다 큰 경우에만 해당 지역의 조우 테이블을 복사합니다. 그렇지 않으면 이전 지역의 조우 테이블이 그대로 유지됩니다.

  • 결과: 비전 시티(Viridian City)에서 노인 튜토리얼을 진행한 후, 다른 풀 지역을 거치지 않고 시나바 섬(Cinnabar Island)으로 날아가면 비전 시티의 조우 테이블이 유지됩니다.

3. 플레이어 이름 저장 방식

  • 문제점: 노인 튜토리얼 중 플레이어의 이름이 임시로 풀 포켓몬 조우 테이블 메모리 영역에 저장됩니다.

  • 결과: 특정 문자(예: 대문자 ‘S’)나 이름 끝의 제어 문자가 MissingNo.의 내부 ID(146)에 해당하는 십진수 80으로 매핑되어, 가짜 MissingNo. 조우 테이블이 생성됩니다.

4. 포켓몬 데이터 처리 및 인덱싱 오류

  • 문제점: MissingNo.의 내부 ID(0)를 포켓몬 도감(Pokédex) ID로 변환하는 과정에서 1바이트 부호 없는 정수(unsigned integer)가 언더플로우되어 255가 됩니다. 이 값이 배열 인덱스로 사용되어 151개 항목의 배열 범위를 넘어선 256번째 인덱스를 참조합니다.

  • 결과: 배열의 끝을 넘어선 메모리 영역(예: 다른 트레이너의 포켓몬 데이터 또는 코드)을 읽어오게 되며, 이를 스프라이트 데이터로 압축 해제하려 시도하여 MissingNo.의 손상된 그래픽이 나타납니다.

5. 인벤토리 아이템 복제

  • 문제점: 포켓몬 도감 ‘발견’ 비트맵 데이터 바로 뒤에 인벤토리 데이터가 저장되어 있습니다. MissingNo.를 조우하면 가상의 256번째 포켓몬을 도감에 기록하려 하는데, 이 과정에서 도감 데이터 영역을 넘어 인벤토리 데이터에 쓰기 작업을 수행합니다.

  • 결과: 인벤토리의 6번째 아이템 수량 바이트의 최상위 비트(high bit)가 설정되어, 아이템 수량에 128이 추가됩니다 (단, 기존 수량이 128 미만일 때).

결론

이 MissingNo. 글리치는 단순히 '버그 투성이' 게임의 결과가 아닙니다. 이는 개발자들이 207바이트의 스택, 단 4개의 범용 레지스터, 그리고 ROM 크기 제한과 같은 엄격한 제약 속에서 어셈블리 언어로 코드를 작성해야 했던 당시의 현실을 반영합니다. 코드 크기 최적화를 위해 바운드 체크를 생략하고 코드 영역을 재사용하는 등의 결정은 당시로서는 합리적이었을 것입니다. 이 사례는 현대 개발자들이 루비(Ruby)나 러스트(Rust)와 같은 고수준 언어와 풍부한 자원을 가진 머신에서 누리는 편의성을 당연하게 여기지 않고, 과거 개발자들의 노력과 제약 사항에 대한 공감대를 형성하는 중요한 교훈을 제공합니다. 이는 소프트웨어 개발의 역사와 진화에 대한 깊은 이해를 가능하게 합니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!