LLM으로 1993년 아미가 게임 어셈블리를 고돗(Godot)에 이식하기
이라크 제재 시기 바그다드에서 순수 68000 어셈블리로 만든 아미가 게임 'Babylonian Twins'의 원작자가 Claude Code를 활용해 7만 줄이 넘는 어셈블리 원본을 분석하고 고돗 4로 이식한 사례입니다. 1년 전 모델은 레벨 포맷 해석에 여러 차례 힌트가 필요했지만, 최신 모델은 한 번에 힌트 없이 해석해내며 추론 능력의 발전을 보여줍니다. 에이전트형 코딩 도구가 레거시 코드 복원·이식에 실제로 활용 가능함을 입증한 사례로 주목받습니다.
1993년, 바그다드에서 나는 Amiga 500으로 Babylonian Twins라는 게임을 만들었다. RAM 512KB, 하드디스크 없이 TV에 연결해서 쓰는 기계였다. 당시 나는 스무 살대의 공학도였다. 순수 68000 어셈블리로, 모든 스프라이트와 모든 스캔라인을 손수 만들었다. Murtadha Salman이 그림을 그렸고 Mahir AlSalman이 음악을 작곡했다. 우리는 제재 하에 있었다. 인터넷도, 게임 개발 자료도 없었고, Amiga 하드웨어 레퍼런스 매뉴얼 한 권이 전부였다. 나는 그 매뉴얼로 하드웨어를 직접 프로그래밍했고, 전기는 하루 몇 시간만 들어왔다. (메모리가 작아서) 끊임없는 플로피 디스크 교체와 섭씨 50도의 여름 때문에 디스크 드라이브를 세 번이나 망가뜨렸다. 왼쪽: 1993년, Amiga에서. 오른쪽: 2026년, 같은 관문 장면. Amiga에서 '손수 만든다'는 건 게임이 실행 중에 운영체제에 아무것도 요청하지 않는다는 뜻이다. 시작할 때 인터럽트 벡터를 저장하고, OS 인터럽트를 끄고, 기계 전체를 차지한다:
move.l #$dff000,a0 ; 하드웨어 레지스터 베이스 lea save(pc),a1 ; 시스템을 확보 move.w #$4000,intena(A0) ; AMIGA로부터
'AMIGA로부터 시스템을 확보'는 1993년에 내가 쓴 주석이다. 그 순간부터 화면은 게임 자체의 코퍼 리스트(Amiga의 프로그래밍 가능한 비디오 보조프로세서)로 처리되며, 스프라이트와 하늘 색상에 맞춰 실시간으로 다시 작성된다. 타일은 블리터(blitter)의 레지스터에 직접 값을 쓰고 완료 플래그를 기다리며 이동한다. 조이스틱은 하드웨어 포트에서 직접 읽고, 발사 버튼은 CIA 칩의 핀 하나다. OS는 레벨 사이에만 잠깐 돌아와서 디스크에서 다음 레벨 파일을 읽고, 곧 다시 꺼진다.
이것은 이라크에서 만든 최초의 상업용 게임이었고, 오랫동안 거의 아무도 플레이할 수 없는 게임이었다. Commodore가 무너지고 제재가 퍼블리셔들을 내쫓아서, 완성된 게임은 선반에 쌓여 있었다. 2008년에 한 Amiga 포럼이 내 동생의 유튜브 업로드에서 이 게임을 발견하고 디스크를 찾아내려고 나를 추적했다. 그 스레드는 아직도 남아 있다.
게임은 이전에 한 번, 2010년에 손으로 이식된 적이 있다. 같은 팀이 처음부터 직접 쓴 엔진으로 iPhone용을 다시 만들었는데, C++ 약 34,000 줄, 몇 달간의 밤과 주말이 걸렸다. Apple과 Google이 피처했고 200만 다운로드를 넘겼다. 그 이야기는 여기에 있다.
이번 이식은 내가 한 것이 아니다. 나는 요청만 했고, 결과물을 매일 밤 플레이했고, 어색한 점을 말했고, 1993년에 그 자리에 있던 사람만 내릴 수 있는 몇 가지 결정을 했다. 파일 포맷 해석과 어셈블리 분석은 AI의 작업이었고, 30년 된 코드를 어떻게 옮길지에 대한 결정들도 그랬다. 그리고 그 속도는 내가 따라가지 못할 정도였다. 이 글은 몇 주 뒤에 앉아서 내 게임에 무슨 일이 벌어졌는지 읽어본 기록이다. 일부는 틀렸고, 나는 몇 주 동안 눈치채지 못했다.
왜 다시 시도했나
예전에 시도한 적이 있다. 1년쯤 전에 이전 모델에게 같은 Amiga 자료를 주고 바이너리 레벨 맵을 해석해달라고 했다. 결국 해내긴 했지만 여러 라운드와 내 힌트가 많이 필요했다. 그러다 Claude Fable 5가 나와서 같은 파일을 줬다. 이건 의도된 테스트였다. 내 추측은 LLM 학습 데이터에 Amiga 어셈블리 코드가 거의 없으리라는 것이었다. 모델이 단순히 기억해내는 게 아니라 추론해서 풀어내는 능력이 더 좋아졌다면, 바로 여기서 드러날 것이다.
7월 4일 연휴가 다가오고 있어서, 이전 단계가 성공해야 다음 단계로 가는 조건부 세 단계를 계획했다. 1단계, 안전한 요청: 내 2010년 엔진, C++ 34,000 줄을 Godot 4로 옮기기. 이것이 대조군이다. 2단계, 불공평한 요청: 생산이 끊긴 기계를 위한 원본 68000 어셈블리 72,758 줄을 — 주석이라곤 거의 없고 C++과 공유점도 없는 — Amiga 원래의 50Hz로 Godot에서 다시 만들기. 3단계, 욕심 많은 요청: 두 번째 것을 첫 번째 안에 넣어서, 현대 게임을 사면 1993년 원작을 실행할 수 있는 보너스로 얻게 하기. 세 가지 모두 성공했다. 1년 전에는 여러 라운드와 내 수정이 필요했던 레벨 포맷이 이번엔 힌트 없이 한 번에 풀려나왔다.
어떻게 실행했나
Claude Code에서 실행해서 터미널과 내 파일시스템에 접근할 수 있게 했다. 파일을 편집하고, (프로그램을) 실행할 수 있었다.