
Zork I를 Python으로 자동 번역하며 영어와 일본어를 병기하여 플레이해 보았다
요약
고전 어드벤처 게임 Zork I의 시나리오 데이터를 Python 기반의 Z-machine인 xyppy를 활용해 실시간으로 일본어 번역하며 플레이하는 과정을 다룹니다. GoogleTrans 라이브러리를 사용하여 텍스트를 번역하고, 캐싱 및 호출 간격 조절을 통해 안정적인 번역 환경을 구축하는 방법을 소개합니다.
핵심 포인트
- Python 기반 Z-machine인 xyppy를 활용한 게임 실행 환경 구축
- GoogleTrans 라이브러리를 이용한 실시간 텍스트 번역 구현
- API 에러 방지를 위한 호출 간격 조절 및 캐싱 로직 적용
- xyppy의 ops_impl.py 수정을 통한 출력 텍스트 가로채기
안녕하세요, tako2입니다.
얼마 전 오픈 소스화된 Zork라는 게임을 알고 계신가요?
저는 영어 텍스트로만 이루어진 어드벤처 게임이라는 것 정도만 알고 오늘까지 왔습니다만, 영어는 기술 서적을 읽을 정도는 되지만 소설이나 이야기 같은 뉘앙스까지 읽어내는 것은 고전하는 수준의 영어 실력이었기에 딱히 신경 쓰지 않았습니다.
이제 와서 오픈 소스화되었다는 사실이 떠올라, 문득 소스 코드가 있다면 최근의 AI 번역을 사용하여 간단하게 일어 번역을 할 수 있지 않을까? 라는 생각에 도달했습니다.
Zork I
곧바로 공개된 리포지토리(Repository)를 살펴보았습니다만, 소스 코드가 보이지 않습니다.
공개된 것은 아무래도 ZIL이라는 형식으로 작성된 시나리오 데이터뿐인 것 같더군요.
약간 기대와 다르다고 생각하면서도, 이 시나리오 데이터를 일어 번역해 버리면 되겠다고 생각하며 게임의 실행 환경을 살펴보기로 했습니다.
뭐, 그 부분은 검색해 보니 브라우저에서 플레이할 수 있는 것을 찾을 수 있어서, 분위기를 맛보기 위해 플레이해 보았습니다.
JavaScript로 구현되어 있어서 브라우저의 번역 기능을 사용하면 일본어로 플레이할 수 있었기에, 이것으로 충분하면 충분하긴 합니다.
그런 이유로, Zork의 시나리오 데이터를 실행하기 위해서는 Z-machine이라는 실행 환경(Interpreter)이 필요합니다.
왠지 실시간으로 번역하는 편이 더 재미있을 것 같다고 생각하여, 그렇다면 Python으로 동작하는 Z-machine이 없는지 찾아보았습니다.
아니, AI에게 물어보았습니다.
실시간으로 번역하고 싶으니 그 부분을 만질 수 있는 것이 좋겠다고 요청했더니, 그렇다면 xyppy가 좋다고 소개받은 것입니다.
xyppy
Python의 버전이나 저처럼 오래된 cygwin에서 동작시키려고 하면 약간 고생하지만, 지금의 Linux 환경이라면 평범하게 동작할 것이라고 생각합니다.
시나리오 데이터도 Zork 리포지토리의 COMPILED 된 것을 사용하면 프롬프트가 표시되지 않는 등의 문제가 있어, ZIL을 빌드하는 환경을 갖추는 등의 경위가 있었습니다만, 그 부분은 생략하겠습니다.
대략 말하자면, 이런 느낌으로 Zork를 기동할 수 있게 됩니다.
$ python -m xyppy zork1.z3
일본어 번역에는 GoogleTrans를 사용했습니다.
DeepL에서도 Python 패키지가 있는 모양이며, 등록하여 API 키를 취득하면 동일한 작업이 가능합니다.
출력 결과를 비교해 보는 것도 재미있을지도 모릅니다.
GoogleTrans
사용법이 매우 간단해서, 이런 느낌으로 작성하면 용이하게 번역할 수 있습니다.
from googletrans import Translator
result = translator.translate("hello world!", dest="ja")
print(result.text)
실제로는 비동기(Asynchronous)이므로 asyncio를 사용하거나, 빈번하게 호출하면 에러가 발생하므로 간격을 두고 액세스하는 등의 궁리가 필요합니다.
번역 함수를 발췌하면, 이런 느낌으로 0.5초 이상 간격을 두거나, 2번 실행해 보거나(이것은 불필요한가?) 하고 있습니다.
같은 문장을 번역하는 수고를 덜기 위해 캐시(Cache)도 준비해 두어, 번역이 발생할 때마다 캐시를 갱신하고 있습니다. 이 캐시는 게임 시작 시에 로드하도록 했습니다.
def trans(s):
global last_trans_time
if s in trans_cache:
...
Python의 Z-machine과 번역 기능은 준비되었습니다.
남은 것은 Z-machine이 출력하는 문장을 가로채서 번역하는 것입니다.
텍스트를 출력하는 부분은 xyppy의 ops_impl.py에서 구현되어 있으며, 이 안에서 호출되는 write()에 의해 콘솔에 문자가 출력되고 있습니다.
하지만, write()에 전달되는 텍스트를 번역하여 교체하면 실시간 번역을 할 수 있을 것이라고 예상했습니다만, 그렇게 간단하지는 않았습니다.
Zork는 40년 이상 전의 메모리가 적은 컴퓨터에서도 동작하도록 하는 궁리가 되어 있어, 빈출 단어를 사전에 등록하거나 이용하는 문자를 한정하고 있습니다.
그 때문에 출력되는 텍스트도 그에 따라 잘게 쪼개져 있기도 합니다.
참고로, ZIL이나 Z-machine의 배경에 대해서는 이 분의 기사가 참고가 되었습니다.
어쨌든, 잘게 쪼개진 텍스트를 하나로 모으지 않으면 의미 있는 번역을 할 수 없다는 것을 깨달았습니다.
그리하여 개행(Line break)이 나타날 때까지 텍스트를 모아두었다가 한꺼번에 번역하기로 했고, 마침내 Zork의 실시간 번역이 가능해졌습니다.
번역 타이밍은 개행 시점이지만, 조금 더 기교를 부렸습니다. 마침표(.)나 느낌표(!)는 문장의 끝이므로 다음 줄에 일본어 번역을 출력합니다. 그렇지 않은 경우에는 아이템 같은 간결한 항목이므로 옆에 일본어 번역을 출력하도록 했습니다.
명령어 입력은 영어 그대로이기 때문에 원문인 영어도 표시된다는 점이 유용하며, 역시 분위기도 살아서 좋습니다!
ops_implp.py의 소스 코드를 gist에 올려두었으니(아래 링크에서), 일본어 자동 번역이 적용된 Zork를 즐겨보시기 바랍니다.
요즘이라면, 이 기사를 참고하여 AI에게 절차를 물어보는 것이 가장 빠를 것 같습니다(아마도).
- Python 설치 (너무 최신 버전이면 좋지 않다는 이야기가 있어서 3.10 정도가 적당할까요?)
- 필요한 패키지 설치 (GoogleTrans 등)
- xyppy의 리포지토리(Repository)에서 파일 입수
- ops_impl.py를 다운로드하여 교체
- 실행!
저도 아직 Zork를 클리어하지 못했기 때문에, 앞으로 마음껏 플레이해 보려고 합니다.
그럼 이만.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기