본문으로 건너뛰기

© 2026 Molayo

HN요약2026. 05. 28. 20:26

Show HN: LLM이 Pokémon을 플레이합니다 (오픈 소스 공개)

요약

LLM이 Pokémon FireRed를 자율적으로 플레이할 수 있도록 설계된 오픈 소스 에이전트 프로젝트입니다. 에뮬레이터 제어, 게임 메모리 기반의 경험 관리, 경로 탐색 및 OCR을 활용한 텍스트 파싱 기술을 결합하여 구현되었습니다.

핵심 포인트

  • RetroArch와 AppleScript를 활용한 프로그래밍 방식의 입력 제어
  • 게임 상태를 데이터베이스에 저장하여 AI의 경험과 문맥 유지
  • 맵 데이터 추출 및 경로 탐색 알고리즘을 통한 내비게이션 구현
  • OCR 기술을 사용하여 게임 내 텍스트와 이벤트를 파싱

Fire Red Agent

개요 (Overview)

이 프로젝트는 대규모 언어 모델 (LLM)이 Pokémon FireRed를 자율적으로 플레이하도록 시도한 저의 결과물입니다. 제가 만든 봇은 게임을 플레이하고, 탐험하고, 전투하며, 게임 이벤트에 대응하는 기본적인 능력을 갖추고 있습니다.

저에게 이것은 TV의 미래입니다. 봇을 만드는 동안, 저는 컴퓨터를 프로그래밍하고 있다기보다 텔레비전 프로그램을 제작하고 있다는 느낌을 받았습니다. 궁극적으로 프로그래밍 방식의 입력 제어 (programmatic input control)와 관련된 기술적 장애물에 부딪혔고, 이로 인해 개발을 일시 중단하게 되었습니다.

데모 영상 시청하기.
기술적 심층 분석 시청하기.

작동 원리 (How It Works)

  1. 에뮬레이터 통합 (Emulator Integration)

저는 Pokémon FireRed를 실행하기 위해 RetroArch를 사용했습니다. 프로그래밍 방식으로 입력을 보내는 데 어려움을 겪었습니다. RetroArch는 UDP 기반의 입력 시스템 (RetroPad)을 갖추고 있지만, 이를 안정적으로 작동시킬 수 없었습니다.

대신, 에뮬레이터에 키보드 이벤트를 보내기 위해 OSA Script (AppleScript)를 사용하는 방식을 택했습니다. 이는 게임 창이 반드시 포커스(focus)되어 있어야 함을 의미했습니다. 이는 제 컴퓨터 전체를 점유하여 백그라운드 작업을 불가능하게 만들었기 때문에 매우 큰 제약 사항이었습니다.

  1. 게임 메모리 관리 (Game Memory Management)

저는 게임 상태 (game state)를 데이터베이스에 저장하여, 이를 AI 경험의 일기처럼 취급했습니다. 시스템은 AI가 시도한 행동, 성공한 것, 실패한 것을 기록하고 그에 따라 조정했습니다.

메모리는 네 가지 다른 유형이 있었으며, AI는 문맥 (context)을 유지하기 위해 가장 최근의 250개를 가져왔습니다. 만약 어떤 행동이 실패한다면(예: 어딘가로 걸어가려다 장애물에 부딪히는 경우), AI는 이를 기억하고 동일한 실수를 반복하지 않도록 피할 것입니다.

  1. 내비게이션 및 경로 탐색 (Navigation & Pathfinding)

AI는 게임 세계 내에서 어디로 이동해야 할지 파악해야 했습니다. 저는 RetroArch로부터 게임 메모리 (Game Memory)를 읽어 들여 맵 데이터를 추출했습니다. 그런 다음 경로 탐색 알고리즘 (Pathfinding Algorithm)을 사용하여 최적의 경로를 결정했습니다. AI는 타일 (Tiles)과 사용 가능한 경로를 기반으로 유효한 이동 옵션만을 고려했습니다. 만약 움직임이 막히면, 인접한 이동을 시도하도록 기본 설정되었습니다 (예: "남쪽으로 걷기", "동쪽으로 걷기" 등).

  1. 게임 텍스트 파싱 (Game Text Parsing)

게임을 이해하기 위해 AI는 게임 내 텍스트를 읽어야 했습니다. PRET의 권고에 따라 텍스트를 위해 직접적인 메모리 추출 방식을 사용하지 않았기 때문에, 주요 지점에서 스크린샷을 찍고 이를 OCR (광학 문자 인식)로 처리했습니다.

이를 통해 AI는 NPC와의 대화, 메뉴 프롬프트 (Menu Prompts), 그리고 기타 중요한 게임 이벤트를 이해할 수 있었습니다. 이는 LLM이 다음에 무엇을 해야 할지 알 수 있도록 안내하는 매우 중요한 역할을 했습니다.

  1. LLM 통합 (LLM Integration)

저는 수집된 모든 정보를 처리하고 의사 결정을 내리기 위해 OpenAI의 GPT-4o를 사용했습니다. 시스템 프롬프트 (System Prompts)는 AI가 반복적인 행동을 피하도록 유도했습니다 (예: 이상해꽃 (Professor Oak)을 여러 번 만나기 전에 파이리 (Charmander)를 잡으려고 시도하는 것 등). 모델은 현재 위치, 가능한 행동, 게임 기억 (Game Memories), 그리고 내비게이션 옵션에 대한 구조화된 데이터 (Structured Data)를 전달받았습니다. 저는 다양한 행동을 장려하고 루프 (Loops)에 빠지는 것을 방지하기 위해 빈도 패널티 (Frequency Penalty)와 존재 패널티 (Presence Penalty)를 실험했습니다.

  1. 전투 처리 (Battle Handling)

전투 핸들러 (Battle Handler)는 상당히 단순했습니다. 그저 A 버튼을 누르는 것이 전부였습니다. 만약 전투가 1분 이상 지속되면, 전투에서 벗어나기 위해 몇 가지 무작위 입력을 보내기 시작했습니다. 이 부분은 개선하고 싶었던 영역이었지만, 저의 우선순위는 우선 AI가 세계를 탐색하게 만드는 것이었습니다.

  1. 상호작용 및 대화 처리 (Interaction & Conversation Handling)

NPC와 대화할 때, AI는 대화를 계속해야 할지 아니면 다음으로 넘어가야 할지를 결정해야 했습니다. 대화 핸들러 (Conversation Handler)는 스크린샷을 찍고, 텍스트를 추출하며, 대화가 여전히 진행 중인지 확인했습니다.

AI가 텍스트를 감지하면 A 버튼을 계속 눌렀습니다. 새로운 텍스트가 나타나지 않으면 스크립트의 다음 부분으로 넘어갔습니다.

중요한 파일/디렉토리

주요 파일 및 디렉토리

어려움 및 개발 중단 이유

가장 큰 난관은 에뮬레이터에 입력을 보내는 것이었습니다.

RetroArch의 UDP 입력(RetroPad)은 저에게 작동하지 않았습니다.

키보드 기반 입력(OSA Script)은 포커스를 필요로 했기 때문에 자동화가 비실용적이었습니다.

Python 기반 솔루션(PiBoy와 같은)이 존재하지만, 저는 Ruby를 선호했고 기존 Python 도구들이 멈추는 문제에 어려움을 겪었습니다.

최종 생각

이 프로젝트는 악몽이자 동시에 엄청나게 재미있었습니다. LLM이 발전함에 따라 이는 더욱 쉬워질 것입니다. 저는 Claude Plays Pokemon이 제가 많은 시간을 들여 사용했던 메모리 파싱을 전혀 하고 있지 않다고 믿습니다. 그들은 단지 메모리를 Claude 3.7로 직접 스트리밍하고, 그것이 알아서 처리하는 것입니다 🤯. 이 작업이 흥미롭다면 주저하지 말고 포크(fork)하여 수정하고 더 나은 무언가를 만드세요!

특별 감사

Griffin R. – 게임 메모리 읽기에 큰 도움을 주었습니다.

Graham Seamens & Parth Patil – AI 로직 지원.

The Pokémon ROM hacking/decompilation community – 그들 없이는 불가능했을 것입니다.

OpenPipe - LLM 관측 가능성(observability).

연락처

저를 LinkedInHacker News에서 만나보실 수 있습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 HN AI Research의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0