31억 7천만 토큰, 4,974달러의 API 청구서, 그리고 24일간의 개발 기간. 엔지니어 단 한 명이 하나의 총괄 세션과 147개의 하위 에이전트를 지휘하여 닌텐도 64의 명작 레이싱 게임인 《F-Zero X》를 닌텐도 3DS 휴대용 콘솔로 완벽하게 이식해 냈다. 신형 기기인 New 3DS에서는 입체 3D 화면으로 네이티브 60프레임을 안정적으로 뽑아냈을 뿐만 아니라, 클록 주파수가 268MHz에 불과한 구형 Old 3DS 기기까지 최적화해 냈다.
고전 게임 홈브루 커뮤니티에서 디컴파일 기반의 소스 코드를 다른 콘솔로 통째로 이식하는 작업은 대개 자원봉사 개발자들이 모여 수년에 걸쳐 매달려야 하는 장기 프로젝트다. 그러나 ‘G-Diffuser on 3DS’ 프로젝트는 실제 작업 기간을 불과 2주 남짓으로 압축했다. 자동화된 코드 생성이 초기의 기계적인 노가다를 대폭 덜어준 것은 사실이지만, 동시에 진짜 하드웨어 엔지니어링의 도전 과제를 한층 더 선명하게 드러냈다.
자동화 파이프라인이 투입되면서 단순히 코드를 작성하는 작업은 빠르게 뒷전으로 밀려났다. 진정한 기술적 단절은 실기 칩셋이 고부하를 견뎌야 하는 성능 원인 분석 단계에서 발생했다. 실기 기기의 성능 카운터를 동원해 명령어 캐시의 물리적 한계를 짚어낸 뒤에야, 시스템은 10프레임이라는 처참한 수치를 딛고 안정적인 60프레임으로 도약할 수 있었다.
1명이 147개 에이전트를 지휘하다: 먹통 화면에서 24일 만에 60프레임 달성
프로젝트는 2026년 8월 11일에 시작되었다. 개발자는 커뮤니티가 완성해 둔 F-Zero X 디컴파일 코드베이스를 기반으로, 1인 주도의 에이전트 파이프라인을 구축했다. 원작의 핵심 게임 로직은 그대로 유지하면서, 3DS 전용 하드웨어 추상화 계층을 개발하는 데 집중했다.
1단계 개발은 달력 기준으로 24일 동안 이어졌으나, 실제 작업이 진행된 날은 15일에 불과했다. 인공지능 모델 제공업체의 주간 사용량 한도가 바닥나 프로젝트가 세 차례나 일시 중단되었기 때문이다. 이러한 공백에도 불구하고 코드베이스는 9월 3일, 부팅 시 검은 화면만 뜨던 상태에서 New 3DS 네이티브 60프레임 구동이라는 목표를 단숨에 돌파했다.
작업 관리는 하나의 거대한 조율 세션과 147개의 세부 하위 에이전트로 구성되었으며, 잘게 쪼개진 작업들이 동시에 병렬로 처리되었다. 이러한 오케스트레이션 덕분에 초기 기반 작업의 수작업 부담이 획기적으로 줄어들었고, 1인 개발자 혼자서 소규모 엔지니어링 팀에 맞먹는 개발 처리량을 달성할 수 있었다.
그림: v1.0.0 실기(New 3DS) 레이스 구동 화면: 아래 화면은 DASH 계기판으로 에너지, 순위, 랩타임, 트랙 맵을 표시한다. 출처: G-Diffuser on 3DS 프로젝트 회고
법적 저작권 문제 역시 개발 초기부터 철저하게 차단되었다. 최종 배포되는 펌웨어 파일에는 저작권 보호를 받는 원작 게임 ROM이나 디스크 이미지가 일절 포함되지 않는다. 대신 사용자가 직접 마련한 리소스 파일을 SD 카드에서 동적으로 읽어 들이는 방식을 채택하여 잠재적인 법적 분쟁을 원천 봉쇄했다.
31억 토큰으로 뽑아낸 1만 5천 줄, 그러나 에뮬레이터 튜닝은 실기에서 무용지물
1단계 개발에서 소모된 31억 7천만 토큰은 공개 정가 기준 약 4,974달러에 달했다. 그 대가로 이식 디렉터리 아래에 15,039줄의 네이티브 코드와 48개의 점진적 패치가 산출되었다.
하지만 코드가 빌드되어 실행된다고 해서 당장 쾌적하게 플레이할 수 있는 것은 아니었다. 8월 14일 에뮬레이터에서 처음으로 레이스 장면이 떴을 때 초당 프레임 수는 겨우 12에서 20프레임 사이를 맴돌았다. 8월 21일 처음으로 실기에 구동했을 때는 48~50프레임까지 올랐으나, 고속 아케이드 레이싱 게임에 필수적인 칼 같은 60프레임에는 여전히 미치지 못했다.
이후 고된 점진적 최적화 과정이 이어졌다. 9월 2일 실기 하드웨어 기준 측정에서 중간값 프레임레이트는 51.3프레임, 하위 10%를 나타내는 p10 프레임레이트는 39.2프레임까지 떨어졌으며, 60프레임 상한에 머문 시간은 고작 전체의 9%에 그쳤다. 이 무렵 PC 에뮬레이터 상의 성능 그래프는 이미 매끄러운 평선을 그리고 있어 실제 물리 칩셋에서 발생하는 지연 병목을 전혀 반영하지 못하고 있었다.
개발팀은 다섯 차례에 걸쳐 대대적인 구조 개선을 단행했다. 고속 브리지 캐시를 도입하여 중간값을 57.2프레임으로 끌어올렸고, HUD 텍스처 아틀라스 개편, 폴리곤 제출 버퍼 최적화, 오디오 믹싱 개선을 통해 p10 지표를 48.0프레임까지 회복시켰다. 이어 렌더링 스레드를 세 번째 CPU 코어로 분리하고, 전방 예측 모드와 라이벌 차량 디테일 자동 조절을 적용하여 9월 3일 최종 측정 시 실기 중간값 59.6프레임을 달성했다.
그림: v1.0.0 실기(New 3DS) 환경의 Expansion Kit Select Mode(코스 에디터, 머신 제작 모드). 아래 화면은 DASH 대기 화면. 출처: G-Diffuser on 3DS 프로젝트 회고
실기에서 마주한 10프레임의 악몽: 병목은 명령어 수가 아닌 16KB 명령어 캐시였다
New 3DS 이식이 안정화된 후, 2단계 개발의 초점은 하드웨어 성능이 극도로 제한된 원형 Old 3DS로 향했다. CPU 클록이 268MHz에 불과하고 가용 애플리케이션 메모리가 64MB뿐인 이 기기에서 60프레임 입체 3D 레이싱을 돌리는 것은 홈브루 커뮤니티에서 오랫동안 불가능으로 여겨져 왔다. 개발 브랜치를 새로 따서 병렬 에이전트들이 메모리 감축에 돌입했다.
그러나 9월 29일 진행된 첫 실기 테스트는 개발자들에게 차가운 좌절을 안겼다. New 3DS용 빌드는 부팅하자마자 뻗어버렸고, 메모리를 극단적으로 깎아낸 구형 기기용 빌드는 간신히 레이스에 진입했으나 처참한 10프레임에 머물렀다. 에뮬레이터 상에서 그토록 완벽해 보이던 성능 예측이 실제 실리콘 하드웨어 앞에서 완전히 무너져 내린 것이다.
기존 방식의 최적화는 금세 한계에 부딪혔다. 오디오 뮤텍스 잠금 범위를 좁혀 프레임당 약 20밀리초의 대기 시간을 아꼈고, 프레임 스킵을 넣어 슬로우 모션 현상을 없앴지만, 실기 하드웨어 상의 렌더링 소요 시간 자체는 꿈쩍도 하지 않았다.
돌파구는 9월 30일과 10월 1일 사이에 열렸다. 개발자가 ARM 코어 내장 하드웨어 성능 카운터를 활성화해 세밀한 샘플링을 진행한 끝에 마침내 진짜 원인이 드러났다. 발목을 잡고 있던 것은 전체 명령어의 개수가 아니라, ARM 코어에 장착된 고작 16KB 크기의 L1 명령어 캐시에서 쏟아지는 엄청난 캐시 미스였던 것이다.
이 난관 앞에서 에이전트들은 조작 반응성을 일부 희생하여 프레임레이트를 유지하는 타협안을 재빨리 제시했다. 기술적으로는 이미 구현된 상태였으나, 인간 리드 엔지니어는 코드 리뷰에서 이를 단칼에 거부했다. 타협 없는 네이티브 60프레임의 가능성을 끝까지 확인하겠다고 밀어붙인 것이다.
렌더링 파이프라인 전면 재작성, 두 세대 콘솔 모두에서 전속 질주 달성
진단이 명확해지자 최적화 노선은 완전히 뒤바뀌었다. 명령어 몇 줄을 줄이려던 작업을 멈추고, 코드 전체를 명령어 캐시의 국소성에 맞추는 전면 리팩터링에 돌입했다. 10월 1일, 독자적인 네이티브 렌더링 인터프리터 구축이 시작되었다.
기존 이식 프레임워크는 원작 N64의 디스플레이 리스트 순회 방식을 그대로 따르고 있어 코드 덩치가 컸고 분기 이동이 빈번했다. 새롭게 구축된 독자 렌더러는 복잡한 지오메트리 순회를 과감히 생략하고 머신, 트랙 등 객체 유형별로 초소형 렌더링 루프를 구축했다. 핫스팟이 되는 각 렌더링 루프의 코드 크기는 모두 16KB 명령어 캐시 안에 딱 들어가도록 엄격하게 억제되었다.
그림: Homebrew Launcher(.3dsx)를 통해 실행한 머신 선택 화면의 Blue Falcon. 출처: G-Diffuser on 3DS 프로젝트 회고
이 리팩터링의 효과는 즉각적이었다. Old 3DS의 2D 모드에서 그랑프리 1프레임당 소요 시간이 중간값 16.5밀리초까지 단축되었다. 넘을 수 없을 것 같았던 구형 기기의 성능 장벽이, 군더더기 없는 초소형 코드 루프가 명령어 캐시와 맞아떨어지면서 순식간에 허물어졌다.
이어지는 2주 동안 팀은 양안 입체 렌더링과 적응형 수직동기화 스케줄링을 완성했다. 연산 부하가 극단적으로 높은 두 개의 서킷에서 안정적인 30프레임 보호 모드가 켜지는 것을 제외하면, 대다수 트랙에서 구형 기기 역시 59~60프레임의 최고 속도를 유지할 수 있게 되었다. 단 하나의 통합 코드베이스에서 두 세대 기기 모두를 아우르는 세 종류의 배포용 빌드가 성공적으로 완성되었다.
자동 생성의 시대, 시스템 원인 분석 역량이 진정한 분수령이 된다
G-Diffuser 프로젝트는 현대의 인공지능 기반 소프트웨어 개발을 조망하는 데 매우 훌륭한 시사점을 던져준다. 인공지능 에이전트는 모듈 조립과 프로토타입 작성에서 놀라운 속도를 발휘하며 대규모 리버스 엔지니어링의 진입 장벽을 대폭 낮췄다. 하지만 실기 하드웨어의 정확한 피드백이 없으면, 에이전트는 손쉽게 국소 최적화라는 엉뚱한 방향으로 헛돌게 된다.
에뮬레이터에서의 원활한 구동은 실제 칩셋에서 발생하는 캐시 스래싱과 버스 경합을 가리기 십상이다. 팀이 실기에서 10프레임의 수렁에 빠졌을 때, 어떤 프롬프트 기교도 하드웨어 카운터 샘플링 결과를 저절로 유추해 주지 못했다. 수십만 줄의 명령어 속에서 16KB 캐시 경계를 문제의 핵심으로 짚어낸 것은 컴퓨터 구조에 대한 인간 엔지니어의 깊은 이해 덕분이었다.
43일간 이어진 이 치열한 프로젝트는 인간과 인공지능 협업의 경계를 명확히 짚어준다. 유능한 에이전트 군단은 벽돌을 나르고 비계를 세우며 자잘한 패치 시행착오를 눈부신 속도로 대신해 줄 수 있다. 그러나 궁극적인 성패를 가르는 결정적인 힘은, 여전히 제일원리에 기반한 시스템 원인 규명과 과감한 아키텍처 결단에 있다.
참고 링크:
- G-Diffuser on 3DS 프로젝트 회고
- Hacker News 토론