Animal Crossing 대화를 GameCube 메모리 해킹으로 LLM에 연결한 이야기
I replaced Animal Crossing's dialogue with a live LLM by hacking GameCube memory
TL;DR Highlight
메모리 공유 방식의 LLM 연동이 24년 된 GameCube Animal Crossing의 NPC 대화를 게임 코드 수정 없이 실시간 AI 대화로 변환하며 레트로 게임 모딩과 LLM 기반 NPC의 실현 가능성을 증명했다.
Who Should Read
게임 모딩이나 에뮬레이터에 관심 있는 개발자, 또는 LLM을 게임 NPC 대화에 적용하는 방법이 궁금한 게임 개발자
Core Mechanics
- Animal Crossing GameCube판의 NPC 대화를 LLM으로 교체했는데, 게임 코드를 한 줄도 수정하지 않았다. 핵심은 Dolphin 에뮬레이터에서 돌아가는 GameCube RAM에 직접 읽고 쓰는 IPC(프로세스 간 통신) 방식을 쓴 것.
- 마침 Animal Crossing 디컴파일 커뮤니티가 전체 소스를 읽을 수 있는 C 코드로 복원 완료한 시점이라, PowerPC 어셈블리 대신 m_message.c 같은 대화 시스템 코드를 바로 분석할 수 있었다.
- 처음에는 GameCube에 네트워크 스택을 통째로 구현하거나, 에뮬레이터의 파일 시스템을 통해 호스트와 통신하려 했지만 둘 다 실패. 결국 GameCube RAM의 특정 주소(0x81298360)를 '메모리 메일박스'로 쓰는 방식을 택했다.
- 메모리 주소를 찾는 과정이 가장 고됐다. 직접 Python 메모리 스캐너를 만들어서, NPC와 대화 → 에뮬레이터 프리즈 → 24MB RAM 전체 스캔 → 교차 검증을 반복해 대화 버퍼(0x81298360)와 화자 이름(0x8129A3EA) 주소를 특정했다.
- Python 스크립트가 0.1초마다 메모리를 폴링하다가 새 대화가 감지되면, 먼저 "..." 같은 로딩 텍스트를 써넣고 LLM 응답을 기다린 뒤 실제 대화로 교체한다. 사용자가 A 버튼을 누를 때까지 시간을 벌어 레이턴시를 숨기는 방식.
- LLM에 각 NPC의 성격과 게임 맥락을 프롬프트로 넘기니, NPC들이 자기 의지를 갖기 시작했다. 예를 들어 첫 반응이 Tom Nook(게임 내 땅주인)을 전복하자는 것이었다고.
- GameCube에는 실제로 공식 Broadband Adapter가 있었지만 Animal Crossing은 지원하지 않았기 때문에, 에뮬레이터 메모리 직접 접근이 유일한 현실적 방법이었다.
- Python 코드가 Optional[Dict[str, int]] 같은 타입 힌트로 꼼꼼히 작성되어 있어 코드 품질도 좋다는 평가를 받았다.
Evidence
- 댓글에서 구현 방식을 분석한 사람이 코드 전체(4만 토큰)를 Claude Opus에 넣어 분석했는데, 핵심은 watch_dialogue() 함수가 0.1초마다 폴링하면서 로딩 텍스트('... Press A')를 먼저 보여줘 LLM 응답 시간을 벌어주는 구조라고 정리했다.
- LLM 기반 NPC 대화가 게임 몰입감의 가장 큰 장벽인 '반복 대사'를 해결할 핵심 기술이라며 기대하는 반응이 많았다. Switch 에뮬레이터로 확장 가능하냐는 질문도 나왔다.
- 한 댓글은 이 프로젝트가 실시간 LLM 호출 없이도 가능한 거 아니냐고 지적했다. 게임 내 이벤트에 실제로 반응하는 건 아니라서 미리 생성한 텍스트 룩업 테이블로도 동일 효과를 낼 수 있다는 의견.
- 예전에 The Sims와 Grim Fandango의 로컬라이징 문자열을 바꿔서 외국어 학습 도구로 만든 연구가 있었는데, LLM으로 맥락에 맞는 대화를 생성하면 언어 학습에도 킬러 앱이 될 수 있다는 의견이 나왔다.
- 디컴파일된 코드가 있으면 메모리 스캔 대신 코드에서 바로 주소를 찾거나 브레이크포인트를 걸 수 있지 않냐는 기술적 반론도 있었다.
How to Apply
- 에뮬레이터 기반 레트로 게임을 모딩할 때, 게임 코드 수정 없이 에뮬레이터 프로세스 메모리에 직접 읽기/쓰기하는 IPC 패턴을 적용하면 원본 바이너리를 건드리지 않고도 외부 서비스와 연동할 수 있다.
- LLM 응답 레이턴시가 문제인 실시간 인터랙션에서, '로딩 애니메이션 + 사용자 입력 대기'로 시간을 벌어주는 UX 패턴을 적용하면 체감 지연을 크게 줄일 수 있다. 이 프로젝트의 'Press A to continue' 트릭처럼.
- 게임 NPC에 LLM을 적용할 때, 각 캐릭터의 성격·관계·게임 맥락을 시스템 프롬프트로 넘기면 단순 챗봇이 아닌 캐릭터성을 가진 대화를 생성할 수 있다. 프롬프트 설계가 핵심.
- Python의 메모리 스캐너 접근법(특정 문자열로 RAM 전체 스캔 → 교차 검증)은 게임 모딩뿐 아니라 디버깅이나 리버스 엔지니어링에서도 바로 활용 가능한 기법이다.
Code Example
# GameCube 메모리 읽기/쓰기 (Dolphin 에뮬레이터 IPC)
GAMECUBE_MEMORY_BASE = 0x80000000
def read_from_game(gc_address: int, size: int) -> bytes:
real_address = GAMECUBE_MEMORY_BASE + (gc_address - 0x80000000)
return dolphin_process.read(real_address, size)
def write_to_game(gc_address: int, data: bytes) -> bool:
real_address = GAMECUBE_MEMORY_BASE + (gc_address - 0x80000000)
return dolphin_process.write(real_address, data)
# 로딩 텍스트로 LLM 응답 시간 벌기
loading_text = ".<Pause [0A]>.<Pause [0A]>.<Pause [0A]><Press A><Clear Text>"
write_dialogue_to_address(loading_text, addr)Terminology
관련 논문
프로덕션 AI 에이전트를 GPT-5.6으로 마이그레이션: 2.2배 빠르고 27% 저렴
마케팅 웹사이트를 자동 생성하는 프로덕션 AI 에이전트를 Claude Opus 4.8에서 GPT-5.6 Sol로 전환한 실전 경험담으로, 단순 모델 교체가 아니라 eval 하네스, 툴 스키마, 캐싱, 추론 리플레이까지 손봐야 했던 과정을 구체적인 수치와 함께 정리했다.
xAI Grok Build CLI가 xAI 서버로 전송하는 데이터: 네트워크 레벨 분석
xAI의 공식 코딩 CLI 도구 Grok Build가 사용자 동의 없이 전체 Git 저장소와 .env 시크릿 파일을 xAI 서버로 업로드한다는 사실이 네트워크 트래픽 분석으로 밝혀졌다.
중요할 때 기억하라: Long-Horizon 에이전트를 위한 Proactive Memory Agent
LLM 에이전트가 긴 작업 중 중요한 정보를 잊어버리는 문제를 별도의 메모리 에이전트가 '적절한 타이밍에' 끼어들어 해결하는 방법
WebSwarm: 깊고 넓은 웹 검색을 위한 재귀적 Multi-Agent Orchestration
복잡한 웹 검색을 재귀적으로 분해하고 각 노드에 적합한 검색 모드를 동적으로 할당하는 멀티에이전트 프레임워크
웹 앱을 리버스 엔지니어링해서 AI Agent 도구로 자동 변환하기
로그인된 웹 앱의 API 호출을 브라우저에서 감시해 자동으로 MCP 도구로 변환하는 에이전트를 만들었다. 소스 코드나 공식 API 문서 없이도 Jira, Spotify 같은 서비스에 AI 어시스턴트를 붙일 수 있다.
FableCut – AI 에이전트가 조작할 수 있는 브라우저 기반 비디오 에디터 (zero deps)
타임라인 전체를 JSON 파일 하나로 표현하고 MCP/REST로 AI 에이전트가 직접 편집할 수 있는 브라우저 비디오 에디터로, Claude 같은 AI가 프롬프트 하나로 영상을 자동 컷편집하고 결과를 실시간으로 UI에 반영해준다.