This site is also available as markdown for AI agents. For a complete index of all pages, see the site index at /llms.txt

Zork와 Comic Chat, 두 개의 클래식 오픈소스 프로젝트를 하나의 게임으로

Read in English →

제가 구독 중인 뉴스레터들 중에 GeekNews라는 개발/기술/스타트업 관련 뉴스 서비스가 있습니다. 작년 말(2025년 11월) 쯤에 해당 뉴스레터로 마이크로소프트가 Zork라는 1980년대 텍스트 어드벤처 게임을 MIT 라이선스로 공개했다는 소식을 들었습니다. 90년대에 NetHack 류의 텍스트 로그라이크 게임들을 플레이해 본 적도 있고, PC 게임 초기에 시에라(Leisure Suit Larry), 루카스아츠(원숭이 섬 시리즈) 등의 그래픽 어드벤처 게임들도 즐겨 했지만, 50이 넘은 아재에게도 Zork와 같은 텍스트 어드벤처는 경험해보지 못한 클래식 장르입니다.

그렇게 ’이런 게임도 있었구나’하고 거의 잊고 지내다가, 지난 달(2026년 7월)에 또 다른 GeekNews 소식이 눈길을 끌었습니다. Zork 프로젝트와 유사하게 마이크로소프트가 이번에는 Comic Chat 이라는 1990년대 IRC 채팅 클라이언트를 오픈소스로 공개했다는 내용이었습니다. Zork와 마찬가지로 Comic Chat도 GeekNews 소식을 접하기 전까지는 있는 줄도 몰랐던 옛날 이야기인데, Comic Chat 소식 페이지 아래에 ’함께 보면 좋은 글’로 링크된 Zork 오픈소스 소식을 보자 머리 속에 떠오르는 생각이 있었습니다.

Zork는 1977년 MIT 학생들이 만든 텍스트 어드벤처 게임으로, 이후 인포컴(Infocom)을 거치며 인터랙티브 픽션이라는 장르를 개척한 대표작 중 하나로 꼽힙니다. Comic Chat은 1990년대 후반 마이크로소프트가 내놓은 채팅 클라이언트로, 대화 내용을 실시간으로 만화 패널로 그려주는 독특한 렌더링 엔진을 가지고 있었습니다. 두 프로젝트는 서로 아무런 접점이 없습니다. 하나는 파서 기반의 텍스트 게임이고, 다른 하나는 채팅 로그를 만화로 바꾸는 렌더러입니다. 그런데 두 프로젝트의 오픈소스화 소식을 함께 놓고 보니 Zork의 텍스트 어드벤처를 Comic Chat의 만화 렌더러로 보여주면 어떨까 하는 아이디어가 떠올랐습니다.

이 글에서는 이 아이디어가 어떻게 ‘그루스 인 코믹’(Grues in Comic)이라는 사이드 프로젝트로 이어졌는지, 지금까지 어떤 방식으로 만들어왔는지, 그리고 퍼블릭 베타를 공개하게 된 과정까지 정리해보겠습니다. (참고로 ’그루스(Grue)’는 Zork에서 불빛 없이 어두운 곳에 들어가면 플레이어를 잡아먹는 괴물로, 인터랙티브 픽션 팬들 사이에서는 일종의 밈으로 통하는 이름입니다. 프로젝트명은 여기서 따왔습니다.)

아이디어: 왜 이 둘을 합칠 생각을 했는가

혹시나 Zork를 플레이해본 분들은 아시겠지만, 텍스트 어드벤처는 진입 장벽이 꽤 높습니다. northtake lamp 같은 명령어를 직접 타이핑해야 하고, 화면에는 텍스트만 흘러갑니다. 반면 Comic Chat은 정반대의 강점을 가지고 있습니다. 캐릭터의 표정과 몸짓, 말풍선을 자동으로 배치해서 텍스트 대화를 만화 장면처럼 보여줍니다.

두 프로젝트를 나란히 놓고 보니, Zork의 게임 플레이 이벤트(방 이동, 아이템 습득, 전투 결과 같은 것들)를 Comic Chat의 만화 장면으로 그려낼 수 있겠다는 판단이 섰습니다. 플레이어는 여전히 텍스트로 명령을 입력하지만, 그 결과는 만화 패널로 렌더링되는 방식입니다. 텍스트 어드벤처의 파서 기반 상호작용은 그대로 유지하면서 진입 장벽이던 텍스트 출력만 만화로 바꾸는 셈입니다.

다만 시작할 때 하나 분명히 정한 원칙이 있었습니다. 이 프로젝트는 두 원작을 그대로 브라우저로 옮기는 이식이 아니라는 점입니다. 원작 소스코드는 각각 ZIL(Zork가 쓰인 인터프리터 언어)과 오래된 C++로 되어 있어서, 브라우저에서 그대로 돌릴 수 없을뿐더러 그렇게 돌리는 것 자체가 목표도 아니었습니다. 대신 원작을 먼저 이해하고, 그 안에 담긴 동작 방식을 추출한 뒤, 이를 ‘중간 표현’(Intermediate Representation, 이하 IR)이라는 독립적인 계층으로 옮겨 담고, 엔진이 이 IR을 실행하는 구조를 택했습니다.

어떻게 만들고 있는가: 원작 이해에서 IR로

실제 작업은 크게 세 단계로 나뉩니다.

첫 번째는 임포터입니다. ZIL로 작성된 Zork I의 소스를 파싱해서 추상 구문 트리(Abstract Syntax Tree, AST)로 만드는 단계입니다. 이 과정을 거쳐 원작이 가진 방(room), 오브젝트, 파서 규칙, 루틴을 모두 프로그램이 읽을 수 있는 형태로 뽑아냅니다.

두 번째는 IR입니다. 여기가 이 프로젝트의 중심입니다. IR은 ZIL에도, 특정 실행 환경에도 종속되지 않는 독립적인 계층입니다. 게임 로직이 특정 실행 환경에 묶이지 않도록 하는 것이 이 계층의 존재 이유입니다. 임포터가 뽑아낸 원작의 게임 플레이를 이 IR로 옮겨 담습니다. (참고로 Grues in Comic은 순수 TypeScript로만 작성되어 있어서, 브라우저에서 별도 런타임 없이 그대로 실행됩니다.)

세 번째는 엔진입니다. IR을 읽어 실제로 게임을 실행하는 런타임으로, 월드 상태 관리, 파서, 전투, 저장과 불러오기까지 Zork I의 동작을 처리합니다. 그리고 엔진이 만들어내는 이벤트를 Comic Chat 방식의 렌더러가 받아 만화 패널로 그립니다. Comic Chat의 패널 배치, 캐릭터 포즈, 말풍선 규칙은 원작 C++ 코드를 직접 참고해서 옮겼습니다.

이렇게 계층을 나눠둔 덕분에 원작과의 정합성 검증도 가능했습니다. 원작 Zork의 플레이 공략(Walkthrough)을 frotz라는 인터프리터로 뽑아 표준 데이터로 삼고, 엔진의 실행 결과를 이 데이터와 한 줄씩 비교하는 방식입니다.

사실 이 프로젝트는 코드 한 줄도 직접 작성하지 않은, 100% 바이브 코딩(vibe coding)으로 만든 결과물입니다. 임포터, IR, 엔진, frotz 기반 정합성 검증까지 앞서 설명한 세 단계 전부를 AI 에이전트가 작성했습니다. 제가 한 일은 프로젝트의 방향성과 세부 요구사항을 정의하고, 플레이어 입장에서 결과물을 직접 플레이하며 테스트하는 것이었습니다. 여기에 더해 Comic Chat 원작에는 배경 이미지 종류가 몇 개 없어서, 이미지 생성 모델로 Zork의 각 방 분위기에 맞는 배경을 추가로 만들고 다듬어 넣는 작업도 제 몫이었습니다.

지금까지의 진행 상황

시작할 때만 해도 갈 길이 멀어 보였지만, 몇 가지 굵직한 이정표는 이미 지났습니다.

  • 임포터와 IR, 엔진 세 축이 모두 완성되어 Zork I을 브라우저 안에서 처음부터 끝까지 완주할 수 있는 상태가 되었습니다. 게임은 실제로 결말(스톤 배로우)까지 도달하며, 이 완주 시나리오는 회귀 테스트로 고정해두었습니다. 이후 엔진 코드를 고칠 때마다 이 완주 시나리오를 자동으로 재생해서, 예전엔 되던 게 갑자기 깨지는 걸 바로 잡아낼 수 있습니다.
  • Comic Chat 방식의 만화 렌더링이 Zork 게임과 연동되어 플레이어의 명령과 게임의 응답이 만화 패널로 그려집니다. 데스크탑 환경의 가로 화면과 모바일 브라우저를 위한 세로 화면 레이아웃을 모두 지원합니다.
  • Zork 원작은 게임 내내 거의 플레이어 캐릭터 혼자 아무 말 없이 진행하는데, Comic Chat의 대화 느낌을 제대로 표현하기 위해서 테이블탑 RPG의 던전 마스터(DM) 역할을 담당할 캐릭터를 추가했습니다. 이 DM 캐릭터는 플레이어(Hero)가 새로운 장소(Room)에 들어갈 때마다 그곳을 소개하는 내레이션을 맡고, 플레이어의 명령에 게임 엔진이 만들어내는 반응을 대사로 표현해줍니다.
  • 랜딩 페이지와 소개 페이지, 자동 생성되는 변경 이력을 갖춘 정적 사이트를 만들었습니다.

퍼블릭 베타를 공개합니다

이렇게 만든 결과물을 서브도메인으로 공개했습니다. grues.danielkimdev.com 에서 지금 바로 플레이해볼 수 있습니다.

그루스 인 코믹 플레이 화면 — 왼쪽은 West of House 시작 장면을 네 컷의 Comic Chat 패널로 그린 모습(Hero와 Dungeon Master 캐릭터 등장), 오른쪽은 look, open mailbox, get leaflet 같은 명령을 입력한 고전 Zork 텍스트 출력

다만 아직은 저장소를 공개하지 않은 단계입니다. 정식 1.0 버전은 저장소 공개와 웹사이트 정식 오픈이 함께 이루어질 때 붙일 계획이며, 그전까지는 베타로 계속 다듬어갈 예정입니다.

마치며

GeekNews에서 우연히 본 소식에서 시작된 사이드 프로젝트가 퍼블릭 베타로 나오기까지 2주가 걸렸습니다. 앞서 이야기했듯 코드는 한 줄도 직접 짜지 않고 100% 바이브 코딩으로 만들었습니다. 적어도 이 프로젝트에서는, 코드를 직접 짤 줄 아느냐가 시작 여부를 가르지 않았습니다. AI 에이전트와 마이크로소프트의 오픈소스화, 이 둘 중 하나라도 없었다면 애초에 시작할 수 없었던 프로젝트입니다. 텍스트 어드벤처와 만화 채팅 렌더러라는, 서로 다른 시대에 서로 다른 목적으로 만들어진 두 코드베이스를 하나의 웹 게임으로 이어붙이는 과정이 이 프로젝트의 가장 재미있는 부분이었습니다.

앞으로도 진행 상황은 이 블로그를 통해 계속 공유하겠습니다.

관련 글

  • 5분 분량

    AI 메모리 도구를 도입했다가 제거한 이유

    코딩 에이전트의 세션 간 컨텍스트 문제를 해결하기 위해 Mem0를 도입했다가 제거한 경험을 공유합니다. 전용 메모리 도구 없이 두 개의 마크다운 파일만으로도 크로스 세션, 크로스 에이전트 연속성을 유지하는 방법을 소개합니다.

  • 3분 분량

    한 공간, 세 가지 역할: 독자가 달라지면 규칙도 달라진다

    개인 메모, 범용 템플릿, 공개 블로그가 한 공간에 뒤섞이면 AI 에이전트도 경계를 구분하지 못합니다. 위키를 네 개의 레이어로 물리적으로 분리한 이유와, 그 과정에서 제 시스템의 어떤 부분이 사실 보편적 원리가 아니었는지 알게 된 이야기.

← 전체 글 목록으로