NOTES · 2026-08-18

한글화 작업 방식은 여러 갈래로 바뀌었다

Localization work split into several evolving threads

기간
2026.02 – 2026.08
대상
게임 프로젝트 12개 + 도구·스킬 프로젝트 3개
근거
실제 대화 기록과 Git 이력

이 문서는 열두 게임 프로젝트의 대화와 Git 기록뿐 아니라 create-kr-patch, emucap, retro-typed-isa로 이어진 도구·스킬 프로젝트의 대화도 함께 본다. 기간은 2026년 2월부터 8월까지다. 프로젝트마다 시작점과 난도가 달랐기 때문에 이를 하나의 성장 단계로 줄 세우지는 않았다.

실제로는 서로 다른 문제가 동시에 누적됐다. ROM을 안전하게 쓰는 방법, 실행 중인 게임을 관찰하는 방법, PoC의 합격 기준, 번역 데이터와 사람의 판단을 나누는 방법, 한글 글자를 원작 화면에 어울리게 만드는 방법이 각각 따로 바뀌었다. 한 프로젝트에서 생긴 원칙이 다른 프로젝트로 건너가기도 했고, 공용 스킬로 옮긴 원칙이 새 게임의 반례를 만나 다시 고쳐지기도 했다.

여기서 프롬프트 전문은 모든 대화를 보관하려고 싣는 것이 아니다. 다음 프로젝트에서 비슷한 상황을 만났을 때, 사람이 어떤 정보를 주고 무엇을 요구하면 조사가 달라지는지 보여 주는 사례만 골랐다.

먼저 구분해야 할 흐름

흐름 처음 드러난 문제 나중에 갖춰진 형태 사람이 계속 맡은 일
ROM 쓰기 raw hex가 읽기 어렵고 서로 다른 패치가 같은 곳을 덮음 TrackedRom·Expected Write·공용 typed ISA 검사해야 할 쓰기 조건을 정함
실행 관찰 사람이 스크린샷과 메모리 값을 옮겨 적어야 함 emucap의 제어·원본/패치 비교·실험 기록·이벤트 범위 재현할 장면과 정상 동작의 의미를 알려 줌
런타임 자산 패치한 바이트가 있으면 게임도 그 자산을 쓴다고 여김 저장·선택·적재·상주·소비를 실제 장면까지 연결 캐릭터 선택, 재진입과 상태 변화의 의미를 알려 줌
PoC 한글 한 글자가 보이면 전체 가능성을 크게 말함 완성을 막는 어려운 조건과 실제 수요를 먼저 확인 최종 결과에서 피할 수 없는 난점을 정함
전체 범위 발견한 파일과 화면을 하나씩 목록에 더함 전체 대상을 먼저 세고 소비 경로별로 나눔 작품에 반드시 있어야 할 장면과 모드를 알려 줌
원본과 빌드 단발성 스크립트와 작업 중간 산출물이 서로 다른 결과를 냄 확인된 원본에서 모든 변경과 배포 패치를 한 경로로 만듦 빌드에 반드시 들어갈 결과와 입력 범위를 정함
번역 작업 원문, 제어코드, 번역 상태와 수정 판단이 뒤섞임 원본 위치 기반 식별자·보호 데이터·단계별 검수 문맥, 말투, 축약과 페이지 분할을 선택함
화면 구성 읽히는 한글을 한 글꼴과 정방향 그래픽으로 넣음 화면별 글꼴·실제 배경 후보·원본 동세와 여백 비교 시각적 위계, 의성어의 동작과 남길 요소를 정함
재사용 선행 패치의 주소·레이아웃·도구가 정답처럼 따라옴 방법은 재사용하되 대상 원본에서 수치와 경로를 재확인 무엇을 참고 자료로 삼을지 정함
공용 스킬 프로젝트마다 같은 원칙을 다시 설명함 반복된 철학을 조건부 불변식으로 정리하고 실전 반례로 갱신 무엇을 공통 원칙으로 승격할지 결정함

이 흐름들은 같은 뜻이 아니다. Expected Write는 typed ISA의 다른 이름이 아니고, emucap은 HITL을 없애는 도구가 아니다. 전체 범위를 세는 일과 모든 항목을 실행해 보는 일도 다르다. 스킬 역시 프로젝트별 판단을 대신하는 정답집으로 만들어진 것이 아니다. 각각 어떤 문제에서 출발했는지부터 봐야 변화의 방향이 보인다.

ROM 쓰기: 읽을 수 있는 코드에서 허용된 변경을 증명하는 코드로

첫 문제는 raw hex의 의미가 보이지 않는다는 것이었다

슈퍼패미컴 마도물어에서 가장 먼저 나온 요구는 기계어를 사람이 읽을 수 있게 만들자는 것이었다.

슈퍼패미컴 마도물어

이제 HEX 대신, Enum/명령어로 Hex를 삽입하는 식으로 할 수 있게 해보자. 지금 Hex로 코드삽입 등을 하니까 디버깅 및 알아보기가 너무 힘들어

이 단계에서 필요한 것은 명령어와 피연산자를 코드로 표현하고, 분기 주소나 명령어 길이를 검사하는 어셈블러였다. 생성된 바이트가 무슨 명령인지 설명할 수 있게 됐지만, 그 바이트를 ROM의 어디에 써도 되는지는 아직 다른 문제였다.

충돌이 반복되자 모든 쓰기 경로를 하나로 모았다

2월 21일 Git 기록에는 ROM 영역 충돌과 추적되지 않은 쓰기를 찾는 검사가 들어왔다. 이 검사가 경고만 내는 동안에는 새 구현이 추적기를 우회할 수 있었다. 다음 날 프롬프트는 리뷰를 더 꼼꼼히 하자는 수준을 넘어, 우회 자체가 어렵도록 구조를 바꾸라고 요구했다.

슈퍼패미컴 마도물어

그리고, tracker를 가진 Rom을 관리하는 특정 구조체를 통해서만 rom에 write를 할 수 있게 Rom을 wrap하는 것으로만 write를 할 수 있도록 아키텍처를 강제하는 설계를 진행해. 이번에도 그렇고 계속해서 무슨 구현마다 tracker를 무시하는 것 때문에 메모리 충돌 문제가 발생하고 있는데, 수많은 코드 속에서 코드리뷰만으로는 더이상 잡아낼 수 없다는 결론이 나왔어.

Git 기록에서는 이 요구가 TrackedRom 도입(64931ec)으로 이어진다. ROM을 바꾸는 모든 코드가 같은 기록 경로를 지나도록 만들어, 새 기능이 검사 밖에서 조용히 쓰는 경우를 막는 것이었다.

Expected Write는 겹치지 않는 것보다 한 단계 더 물었다

같은 날 이어진 질문은 “어디에 썼는가”만 기록하지 않고 “쓰기 전 원본이 무엇이어야 하는가”를 선언하게 했다.

슈퍼패미컴 마도물어

이제 그러면, Expectation logic을 rom write쪽에 줘보려고 해. 내가 특정요소의 원본 롬에 FF 또는 00 등 위치에만 실제로 write를 수행중인, 또는 이 요소가 Overwrite를 할 수 있으며 어디든 상관 없는지 등 expectation을 위해서. 이러한 구조는 도움이 될지 평가해봐.

그 결과는 TrackedRom Expect(76bcb0e)로 남았다. 여기서 서로 다른 검사가 나뉜다.

  • 쓰기 추적은 어느 기능이 어느 범위를 바꿨는지와 기능끼리 겹치는지를 본다.
  • Expected Write는 쓰기 직전의 원본 바이트가 선언한 값이나 빈 공간 조건과 맞는지 본다.
  • typed ISA는 새로 만드는 실행 바이트가 선언한 CPU 명령으로 해석되는지 본다.

세 검사는 함께 쓰이지만 서로 대신할 수 없다. 충돌이 없더라도 잘못된 원본 버전에 쓸 수 있고, 예상한 빈 공간에 썼더라도 잘못 인코딩된 명령어일 수 있다.

한 프로젝트의 장치가 공용 방법으로 옮겨 갔다

세가 새턴 마도물어에서는 슈퍼패미컴판의 구조를 가져오되 디스크 쓰기에 맞게 다시 만들었다.

세가 새턴 마도물어

또한, ../snes_madou 코드베이스에서 강점들을 따오자. 롬에 덮어쓰는 경우 충돌이 일어나는지, 또는 우리가 기대하지 않은 값을 덮어쓰는지를 확인하자. 또한, 코드 리뷰어 4명 (존 카맥, 리누스 토발스, 러스트 프로그래밍 전문가, 어셈블리 프로그래밍 전문가)의 리뷰를 거쳐서, 코드베이스를 리팩토링하자. 테스트 파일도 따로 분리하는 패턴으로 가고. 최종적으로는 모든 덮어쓰는 행위는 감시되고 컨트롤 되어야만 해. 또한, 우리는 최종적으로 목적이 844 글리프를 유지하는것이 전혀 아니야. 확장이 결국 목표니까, 이들도 고려해서 진행해봐.

그날 Git 기록에는 TrackedDisc(911758c)가 들어왔다. 7월 게임기어판에서는 공용 원리를 더 짧게 다시 설명했다.

게임기어 마도물어 I

자매 프로젝트들에서 핵심은 1. 예측되는 공간에만 쓰기, 2. 우리 쓰는 기능끼리 충돌하지 않기거든.

게임기어판에는 원본 바이트, 빈 공간과 빌드 후 미추적 쓰기를 확인하는 게이트가 차례로 들어갔다. 7월 메가드라이브판에서는 raw bytes나 외부 asm 파일을 최종 빌드 입력으로 두지 말자는 요구가 다시 나왔다.

메가드라이브 마도물어 I

지금 ISA가 구현된 Enum 구조는 있어? SNES Madou나 SS Madou 등 참고하고. 빌드 파이프라인에는 기본적으로 바이트를 그대로 쓰거나 asm파일로 작성된건 acceptable해선 안되는게 원칙이니 미리 기억해두고

8월에는 프로젝트마다 있던 ISA 구현을 공용 라이브러리로 모으기 시작했다.

typed ISA

이 프로젝트는 부모 디렉토리에서 rust 기반의 typed ISA들을 라이브러리화하는 것이야

typed ISA

여기로 가져올거 아니야? 애초에 에뮬레이션이 목표가 아니라 expected write 구조와 정적분석이 여기 목표야. 저건 동적분석에서 할일이고

retro-typed-isa의 Git 기록에는 여러 CPU 프로필과 Expected Write 검증 규칙이 8월 7일에 함께 들어왔다. 이후 슈퍼패미컴·드림캐스트·게임기어·메가드라이브 프로젝트가 공용 구현으로 옮겨 갔다. 이 흐름은 “hex 대신 enum” 한 번으로 끝나지 않았다. 읽을 수 있는 명령, 쓰기 경로의 단일화, 원본 사전조건, 프로젝트 간 공용 검사 규칙이 각각 다른 실패를 거치며 추가됐다.

다음 프로젝트에서 비슷한 문제가 생기면 프롬프트에는 최소한 다음 질문이 들어가야 한다.

  • 최종 산출물을 바꾸는 모든 경로가 같은 추적 인터페이스를 거치는가?
  • 각 쓰기는 기존 바이트, 빈 공간, 허용된 덮어쓰기 중 무엇을 기대하는가?
  • 두 기능의 쓰기 범위가 겹치면 빌드가 실패하는가?
  • 실행 코드는 선언한 CPU 프로필의 명령어로 생성되고 다시 해석되는가?

실행 확인: 사람이 옮겨 적던 HITL에서 재현 가능한 관찰로

초기 HITL은 사람에게 디버거 조작을 많이 맡겼다

2월 슈퍼패미컴판에서는 에이전트가 절차를 적고, 사람이 Mesen에서 장면을 만든 뒤 값과 결과를 답변 파일에 옮겼다.

슈퍼패미컴 마도물어

지금 프로젝트를 파악해서, 월드맵 VRAM 유출 문제를 해결할 Mesen HITL 절차를 하나 만들어봐.

슈퍼패미컴 마도물어

mesen_debug/HITL_S_ANSWER.md에 1~3 기록 남겨뒀어.

이 방식은 사람이 알고 있는 게임 상태를 조사에 넣는 데는 효과가 있었다. 반면 같은 장면을 다시 만들거나 JP와 KR을 맞춰 비교하려면 저장 상태, 조작 순서, 메모리 값과 스크린샷을 계속 주고받아야 했다. 관찰 전에는 완료를 말할 수 없다는 경계도 사람이 따로 세워야 했다.

슈퍼 나조 뿌요 루루의 루

내가 HITL도 안했는데 왜 해결되었다는 판정을 내린거지? 메모리에 기록해둬. HITL전에 해결되었다고 쓰지말라고

초기 HITL의 교훈은 사람이 에뮬레이터를 오래 조작해야 한다는 것이 아니었다. 정적 빌드 성공과 실제 소비 경로의 확인은 다른 증거라는 점, 그리고 사람만 알고 있는 장면 조건을 조사에 넣어야 한다는 점이었다.

emucap은 그 관찰을 에이전트가 다룰 수 있게 하려는 데서 시작했다

6월 23일 첫 프롬프트에는 사람이 특정 시점을 표시하고, 에이전트가 그 전후 상태와 화면을 읽는 도구라는 목적이 구체적으로 적혀 있다.

emucap

/create-kr-patch:create-kr-patch 이 프로젝트는 Emulator에서 "특정 키 조합"을 누르면, Monitor 등을 통해 프로세스를 감시하는 AI Agent가 이 시점 및 이전 시점들에서의 상태값과 스크린 화면 등을 파악할 수 있고 (또는, 사람이 임의 시점에서 키조합을 통해 "녹화"를 시작하면 그 시점부터 "중단" 시점까지의 메모리 state 및 스크린샷을 파악하거나), 이에 대해 사람이 문제점을 설명하면 AI가 문제를 분석할 수 있게 만들어주는 툴을 개발하는 것이야. 다양한 Emulator를 지원할 생각이고. Skill에서 일반적인 패치 방법론을 설명하고 있으니, 이를 기반으로 어떻게 이 프로젝트가 더 도움이 되는 기능들을 제공할 수 있을지 아이디에이션부터 진행해보자

같은 날 Git 기록에는 ROM 해시가 붙은 기록 묶음과 Mesen2 회고 덤프가 생겼고, 이어서 메모리 읽기·스크린샷·상태 확인을 제공하는 라이브 제어가 들어왔다. 다음 날에는 입력, 세이브 상태, 브레이크포인트와 프레임 진행까지 확장됐다.

화면 캡처 도구에서 비교 실험 도구로 넓어졌다

개발 하루 뒤의 프롬프트는 같은 입력과 상태에서 원본과 패치판이 처음 갈라지는 지점을 찾도록 요구했다.

emucap

현재 아이디어인데, rom 두개에서 동일하게 실행되었을 때 diff를 볼 수 있으면 좋겠거든? 동일 Seed로 게임을 시작할 수 있나? JP Rom vs KR 패치중인 Rom에서 만약 KR 패치중인 Rom에서 문제가 생겼을 때 뭐가 문제인지 파악할 수 있게. WRAM/VRAM/Palette/Reg/DMA 등 요소들 전반 체크 되게

이에 따라 상태 덤프, 세이브 상태 이분, JP·KR 교차 비교가 추가됐다. 사람이 화면 두 장을 보고 “다르다”고 말하는 데서 끝나지 않고, 동일한 시작점과 진행량 아래에서 메모리·레지스터·DMA의 첫 차이를 좁혔다.

마지막에는 스크린샷보다 실험 기록의 연결이 중요해졌다

7월 PCE-CD판에서 나온 프롬프트는 캡처 파일을 많이 남기는 것과, 무엇을 바꾼 뒤 어떤 상태에서 무엇이 달라졌는지 기록하는 일을 구분했다.

PCE-CD 마도물어 I

계속 스크린샷을 증거가 아닌 형태로 쌓지말고 emucap track을 쓰고 같이 증거로써 남겨

PCE-CD 마도물어 I

아니 쌓지말라는 의미는 현재 무슨 일이 일어나는지 저장이 안되면 내가 어떤 수정이 있었는데 어떻게 변경되었는지 어떻게 알아. path에 저장하고 mem에만 쌓지 말라고. 증거가 아닌 형태로

emucap에는 6월 말부터 실행 입력, 상태와 화면을 한 실험에 묶는 tracking이 들어와 있었다. 8월에는 정해진 구간만 녹화하고, 특정 사건이 몇 번째 발생할 때 멈추거나, 준비 구간과 관찰 구간에서 받을 이벤트를 따로 정하는 기능까지 추가됐다.

도구가 맡는 부분이 늘어도 사람은 “두 번째 실패 뒤에만 나오는 힌트”, “초록 뿌요에게 아이스스톰을 쓴 장면”, “이 문장이 정상이라면 다음 화면은 무엇이어야 하는가”를 알려 준다. 에이전트와 도구는 그 상태를 재현하고, 원본과 패치판을 맞추고, 관찰을 실험 기록으로 남긴다. 사람이 매번 주소와 레지스터 값을 옮겨 적는 일은 도구로 넘어갔다.

다음 프로젝트의 관찰 프롬프트에는 장면 이름만 적기보다 다음 정보가 유용하다.

  • 어떤 시작 상태와 입력 순서로 문제를 재현하는가?
  • 첫 실행, 두 번째 실행, 특정 캐릭터나 주문처럼 가설을 가르는 조건은 무엇인가?
  • JP와 KR을 비교한다면 seed, 세이브 상태, 진행 프레임과 입력을 어떻게 맞출 것인가?
  • 캡처가 어느 원본 해시와 빌드에 연결되어야 하는가?
  • 사람이 판단해야 할 화면 의미와 도구가 자동으로 기록할 값은 각각 무엇인가?

런타임 자산: 파일에 들어간 것과 게임이 쓴 것을 가르다

실행 관찰을 자동화해도 한 질문은 남는다. 패치한 글꼴이나 문장이 ROM에 들어 있다는 사실만으로는 게임이 그 데이터를 읽었다고 할 수 없다. 읽었다고 해도 다른 로드가 바로 덮을 수 있고, RAM에 남아 있어도 화면을 그리는 코드가 다른 버퍼를 볼 수 있다. 이 차이는 emucap이 생기기 전부터 여러 게임에서 반복해서 드러났다.

한 번 쓴 데이터가 다음 상태에서도 남는지 물었다

슈퍼 나조 뿌요 2에서는 퍼즐 조건 글자를 VRAM에 한 번 넣어 현재 화면을 맞추는 시도가 있었다. 사람은 이 게임에서 한 판에 2~6개의 조건이 차례로 바뀐다는 규칙을 알고 있었다.

슈퍼 나조 뿌요 2

다른게 계속 덮어씌우는거아니야? 이건 한번 깨고 끝이 아니라 각각 조건을 가진 2~6개의 퍼즐을 풀어야하는건데, 조건은 계속 바뀔테니까 또. 그때그때 계속 넣고 있어? 한번만 우리가 덮어씌우려고 하는게 실수일 수 있을거고

사람의 지적 뒤 초점은 첫 화면의 모양에서 데이터의 수명으로 옮겨 갔다. 4월에 만든 고정 덮어쓰기는 당장의 조건을 보여 줬지만, 6월 동적 확인에서는 게임의 일본어 CHR 로드가 더 늦게 와서 한국어를 다시 덮는 경우가 확인됐다. Git 이력의 97a944b는 30프레임 동안 반복하는 임시 방식 대신, 조건 화면이 실제로 살아 있는 동안만 한국어 DMA를 보내는 게이트로 바뀐 기록이다. 중요한 것은 몇 번 덮어썼느냐가 아니라 어느 상태가 시작되고 끝날 때 자산이 유효해야 하는지였다.

캐시는 파일보다 게임 진행 순서에 묶여 있었다

세가 새턴 와쿠와쿠판에서는 캐릭터마다 필요한 글자가 달라 세 개의 ROM을 만드는 우회가 한때 구현됐다. 각 파일을 따로 켜면 글자가 나왔지만, 플레이어가 캐릭터를 바꿀 때마다 패치를 바꾸는 결과였다.

세가 새턴 와쿠와쿠 뿌요뿌요 던전

우선 지금 bin/cue들 out쪽에 있는거 다 날려줘. 저 3ROM 방식은 진짜 말도 안되는 짓거리야. 이건 소프트웨어가 아니라 게임이라고. 실기 패치를 하는 사람도 있는데 3ROM 배포같은 짓을 한다고? 캐시 구조를 애초에 파악해야하는 이유가 뭐지? 첫 로드는 지금 나만 해보고 있는거 아니야? 그냥 내가 에뮬레이터 캐시 날리면 끝 아닌가?

세 산출물은 기술적으로 가능했지만 한 게임 안에서 캐릭터가 바뀌는 경험을 충족하지 못했다. 이어진 질문은 파일 교체가 아니라 실제 적재 시점을 겨냥했다.

세가 새턴 와쿠와쿠 뿌요뿌요 던전

재로드를 하는게 맞는지가 문제거든. VRAM? 같은곳에 올라가는거 확실해?

세가 새턴 와쿠와쿠 뿌요뿌요 던전

이게 히트하는 순간은 던전 진입 시점이네. 전체 플로우 떠올려. 내가 플레이하는 캐릭터가 아르르기때문에 이런 로드가 일어난 기분이라고 보면 되겠네.

캐릭터 선택, 캐릭터 OPEN, 게임 맵과 던전 진입은 서로 다른 상태였다. 캐릭터 선택에서 브레이크포인트가 안 걸렸다고 로더가 없다고 결론 내릴 수 없었다. Git 이력에는 루트별 세 벌의 글꼴을 만든 뒤 로드 시점을 추적하고, 결국 세 벌 구조를 걷어 내 한 ROM의 단일 글리프 표로 돌아간 과정이 남아 있다. 캐시를 비우고 첫 실행만 맞추는 실험은 캐릭터를 바꾸고 다시 들어오는 플레이를 증명하지 못했다.

저장 공간과 실행 중 글리프 자리는 서로 다른 한계였다

PC-98판에서는 외자 188칸이 보이자 이를 게임 전체의 글리프 저장 한계로 오해할 수 있었다. 사람은 그 숫자가 어디에서 생겼는지 다시 물었다.

PC-98 마도물어 1-2-3

글리프 캐시는 어디에 위치하지? 항상 그곳에서만 읽어오게 되어있나?

PC-98 마도물어 1-2-3

그런데 원래 일본어 게임은 그러면 저 188자리가 아니라 다른 공간에서부터 글리프를 읽어온다는거지?

디스크에 넣을 수 있는 글꼴의 총량, BIOS 외자 영역에 한 번에 등록할 수 있는 수, 현재 화면에서 동시에 필요한 글자는 같은 숫자가 아니었다. 이 구분이 생기자 “188자 안으로 번역을 줄인다”가 아니라, 디스크의 글꼴을 장면에 맞춰 실행 중인 슬롯으로 공급하는 방향을 조사할 수 있었다. 사람이 제공한 것은 캐시 주소가 아니라, 188이라는 수치가 게임 전체의 한계라는 설명이 정말 맞는지 되묻는 기준이었다.

프로젝트에서 반복된 구분이 스킬의 한 축이 됐다

7월 스킬 재구성 때 이 문제를 폰트나 압축의 부속 항목으로 두지 말자는 질문이 나왔다.

create-kr-patch

runtime-assets가 현재 시점에서 어떤 하나의 축으로써 가야할 것인가가 핵심인것 같은데

8분 뒤 Git 이력의 1224270은 런타임 자산 도달성(runtime asset reachability) 문서를 새로 만들었다. 여러 프로젝트의 표현을 합치면 확인할 연결은 다음과 같다.

  1. ROM이나 디스크의 어느 자산을 빌드가 바꿨는가.
  2. 파일표, 포인터, 장면 분기가 그 자산을 고르는가.
  3. 실제 로더와 압축 해제 코드가 기대한 데이터를 RAM이나 VRAM으로 보냈는가.
  4. 다른 화면이나 캐시 갱신 뒤에도 필요한 동안 그 데이터가 남는가.
  5. 마지막 렌더러가 그 메모리를 읽어 화면에 썼는가.

한 화면이 맞았다는 사실은 그 실행 경로와 그 시점까지를 증명한다. 다른 캐릭터, 재진입, 오버레이 교체나 두 번째 로드는 자산의 선택과 수명을 바꿀 때만 별도 확인이 필요하다. 파일 수만큼 실행할 필요는 없지만, 다른 소비 경로를 같은 사례로 대신해서도 안 된다.

사람은 여기서 주소를 대신 찾지 않았다. 캐릭터를 바꾸면 어떤 화면을 거치는지, 조건문이 언제 갱신되는지, 같은 듯 보이는 장면이 실제로는 다른 진입 경로인지 알려 줬다. 에이전트는 그 게임 지식을 바탕으로 첫 번째로 끊긴 연결을 찾고, 정적 범위와 실행 증거를 나눠 기록했다.

다음 프로젝트에서 자산이 “적용됐다”고 확인할 때는 다음처럼 물을 수 있다.

  • 빌드 결과 안에 바이트가 있다는 것과 게임이 그 자산을 골랐다는 것을 각각 무엇으로 확인했는가?
  • 로드나 변환 뒤 어느 RAM·VRAM 영역에 머물며, 언제 다른 데이터가 그곳을 덮는가?
  • 첫 실행, 캐릭터 전환, 화면 재진입과 저장 상태 복원 중 자산의 수명을 바꾸는 조건은 무엇인가?
  • 한 실행 사례가 같은 경로를 쓰는 파일 범위를 정적으로 설명할 수 있는가?
  • 사람이 알려 줘야 할 게임 상태와 도구가 추적해야 할 메모리 연결은 무엇인가?

PoC: 한글 한 글자에서 완성을 막는 조건으로

한 글자 PoC가 증명하는 범위가 너무 넓게 쓰였다

한글 한 글자를 띄우는 PoC는 렌더 경로, 글리프 형식이나 인코딩의 일부를 빠르게 확인할 수 있다. 하지만 전체 번역에 필요한 글리프 수, 재배치, 동적 적재와 다른 화면의 렌더러까지 증명하지는 못한다. 6월에 스킬을 검토하면서 이 차이를 실제 프로젝트 사례로 다시 물었다.

create-kr-patch

현재 스킬에서 PoC가 조금 과장된 감이 있다고 보여. 한글 1자 교체만으로는 글리프 부족 문제, Relocation 가능성 등을 알기 좀 힘들어. 부모 디렉토리에 실사례들이 차라리 좀 더 많은데, 기본적으로 문제가 생기는 플로우는 1. 텍스트들을 뽑음. 2. 글리프 가용 공간을 대략 산출하고, 번역을 함. 3-a. Dynamic Font Loading 등이 불가능해서 글리프가 많이 초과될 가능성이 높음 -> 기존 탐사를 바탕으로 글자로 바꿔도 되는 공간들을 찾고, LLM + HITL 기반으로 저빈도이거나 | 일괄 치환이 가능한 문자를 지워나가야 함. 3-b. 실제로는 시스템적으로 특정 부분은 Relocation 등이 불가능해서 전반 글자수나 문장의 글자수를 줄여야하는 경우 등이 있는데 글자를 이 과정에서 3-a처럼 줄임. 대충 이런 순으로 한글패치가 실제로 이루어지거든. 그리고, 한글 1자 교체가 항상 가장 빨리 인지할 수 있는 영역에서 시작되어야한다는 내용이 있는지 궁금하네. 이 내용들이 종합되어서 PoC가 단계별로 설계되어야하는데, 1자 패치 한가지로는 약간 애매한듯 함. (성취감이나 가능성 탐사, 렌더링 경로 확인의 일부까지는 되지만 글리프 공간/인코딩 공간 쪽은 좀 애매) 부모 디렉토리쪽에 실제 한글화 패치와 수많은 여정들이 있었던 것들이 있었는데 그런 쪽에서 한번 어떤 PoC 단계가 실제로 더 있어야할지 과정을 찾아와봐. Waku Puyo 같은 예시에서는 안쓰이는 16x8 공간을 어거지로 16x16으로 회수해서 사용하거나, 빈공간인줄 알았던 글자 위치가 사실 배경 타일 위치였어서 reserved 위치로 둔적도 있었는데, 글리프 공간 부족이 예상되면 확장 가능성이 있는지에 대한 PoC가 스킬에는 없는거거든. 설계를 위해서 조사들을 좀 하자. 또한, 좀 어쩔수 없긴 하지만 기존 한글화에서 한가지 빠진게 바로 "이름 입력"이라는 요소같은게 있거든? 혹시 외부 사례가 있는지 찾아봐주면 좋을 것 같고

이 프롬프트는 PoC를 없애자는 말이 아니다. PoC가 답해야 할 질문이 “한글을 띄울 수 있는가”에서 “완성할 때 실제로 막힐 조건을 넘을 수 있는가”로 바뀌었다.

create-kr-patch

지금 이 레포지토리 스킬에서, 내가 PoC의 방향은 저위험한 방향을 찾는게 아니라, 결국 한글패치에서 반드시 성취되어야하는 Goal로가는 블라커가 해결될 수 있는 것을 탐사하는 과정이라는 방향성이 철학에 녹아있을까?

게임 프로젝트에서는 가장 어려운 조건을 먼저 지정했다

게임기어판을 다시 시작할 때도 같은 질문이 구체적으로 나왔다.

게임기어 마도물어 I

create kr patch 방법론으로써는 우선 난이도가 가장 높은 문제를 해결해야해. 최종적으로 결과물을 상상했을때 뭐가 블로커로써 가장 골치아픈지 생각하고, 그것부터 해결하자

PC-98판에서는 188칸의 외자 영역에 한 글자를 넣는 시연보다 전체 번역에서 요구할 글리프 양을 먼저 문제 삼았다.

PC-98 마도물어 1-2-3

그렇게 해봐. 단 최소 PoC는 별로 의미없다고 봐. 저위험이 목표가 아니라 우리는 결국 굉장히 많은 글리프가 필요하게 될거니까

PC-98 마도물어 1-2-3

파일 하나 빌드해봐. 한글 전체 되있는 상태로 볼 수 있나? 사람 검수는 기본적으로 글리프와 관련된 확신이 있어야 진행될 수 있어

전체 문장을 넣자 빌드와 화면이 무너졌고, 188이라는 숫자가 디스크에 저장할 수 있는 총 글리프 수가 아니라 동시에 등록되는 외자 슬롯의 한계라는 점을 다시 조사하게 됐다. 필요한 글자를 동적으로 공급하는 구조를 먼저 마련한 뒤에야 번역 검수를 계속할 수 있었다. 작은 성공을 더 많이 보여 주는 것보다 전체 수요를 한 번 넣어 본 실패가 설계를 더 크게 바꾼 사례다.

슈퍼 뿌요뿌요 2에서도 한 글자가 보인다는 사실보다 전체 글리프 수요를 처리할 수 있는지를 먼저 물었다.

슈퍼 뿌요뿌요 2

그런데 전체 한글 빌드 해봐도 되는거 아니야? 어차피 지금 중요한건 이 시점에서는 한글이 나오냐가 아니라 다 나오게 만들 수 있냐잖아

다음 프로젝트에서 “PoC를 해 달라”는 말만 쓰면 가장 쉬운 화면이 선택될 수 있다. 다음 내용을 함께 주는 편이 낫다.

  • 완성된 패치에서 반드시 되는 소비 경로와 가장 큰 수요는 무엇인가?
  • 현재 PoC는 렌더 경로, 인코딩, 저장 공간, 런타임 슬롯 중 어디까지만 증명하는가?
  • 최악 조건의 문장·글리프·파일을 넣었을 때도 같은 설계가 버티는가?
  • 이 시험이 실패하면 어떤 설계를 바꾸고, 성공하면 다음에 어떤 위험을 확인할 것인가?
  • 쉬운 첫 화면보다 이후에 피할 수 없는 어려운 조건을 먼저 고를 수 있는가?

전체 범위: 눈앞의 성공을 늘리기 전에 분모부터 세다

초기 프로젝트에서는 실행 중 발견한 문자열과 화면을 목록에 하나씩 더하는 일이 많았다. 새 단서를 찾는 데는 쓸 만하지만 “얼마나 남았는가”에는 답하지 못한다. 작품의 전체 구조를 먼저 세고 자동 추출 결과가 그 구조를 설명하는지 비교하면서 조사 방식이 달라졌다.

사람이 아는 작품의 크기가 추출기의 첫 검사가 됐다

메가드라이브 마도물어의 초기 추출은 5층 부근까지만 설명했다. 사람은 주소나 파일 형식을 제시하지 않고 게임의 실제 층수를 알려 줬다.

메가드라이브 마도물어 I

뭔가 한가지 이상한게 있거든? 이 게임은 1~5층짜리 게임이 아니라, 11층까지 + 지하 4층까지 있는 게임이야. 혹시 뭐 텍스트 뱅크 누락된거있나?

다섯 층 분량의 추출과 11층·지하 4층짜리 작품이 동시에 맞을 수는 없다. 어느 뱅크가 빠졌는지 곧바로 답하지 않았지만, 추출 완료라는 판단을 철회하고 다른 뱅크와 참조 경로를 다시 보게 했다.

PC-98판에서도 정돈된 추출표가 먼저 나왔다. 후보를 거르는 동안 세 편짜리 RPG의 이야기가 460개 안팎으로 줄어들자 사람이 수치 자체를 의심했다.

PC-98 마도물어 1-2-3

이 게임이 스토리가 460밖에 안될리는 없지 않을까? 상식적으로?

같은 날 Git 기록에서 뒤이은 변화가 보인다. 메시지를 포인터 차이마다 잘못 잘라 445개로 축소했던 파서를 고치자 1,514개가 나왔고(a5be2f5), 512개짜리 포인터 표 뒤에 있던 메뉴·아이템 텍스트 구역까지 찾으면서 MENUDAT의 전체 구조가 다시 바뀌었다(2f92054, 70845ea). “상식적으로 적다”는 느낌이 최종 증거는 아니지만, 그럴듯한 오답을 완료로 굳히지 않는 강한 경보였다.

전체 초벌은 번역 완료가 아니라 기술 수요를 드러냈다

슈퍼 뿌요뿌요 2에서는 앞 장의 “전체 한글 빌드” 질문 뒤 273개 초벌 대사와 433자 글리프 수요를 한꺼번에 넣었다. Git 이력의 7949b92가 그 전체 이야기 빌드다. 작은 시연에서는 숨었던 누락 글자와 대사창 감김이 이때 드러났다.

대사 전체가 빌드됐다고 게임 전체가 목록에 들어오지는 않았다. 첫 메뉴에서 찾아낸 그래픽 글자 세 개를 보고 사람이 다시 범위를 넓혔다.

슈퍼 뿌요뿌요 2

이 "글자"가 3개로 끝나는게 아니라, "옵션"이나 각 서브메뉴로도 더 많이 있거든. 체크해봐

다음 Git 기록 951c0a7은 모드 선택, 옵션과 하위 메뉴를 별도 한글화 표면으로 정리했다. 번역 문장 수, 필요한 글리프 수와 한글화할 화면 수는 서로 다른 분모였다. 어느 하나가 100%라고 다른 두 범위까지 끝난 것은 아니다.

1,100개 파일은 1,100번 실행하라는 뜻이 아니었다

전체를 놓치지 말라는 원칙과 emucap을 함께 쓰자 반대쪽 문제가 생겼다. 모든 파일을 실제로 한 번씩 띄우려는 접근이었다.

create-kr-patch

내가 지금 에이전트들로 부딫힌 문제가, 이 원칙들과 emucap을 조합해보니 파일이 1100개면 런타임으로 한땀한땀 1개씩 뭔가 튀어나오는걸 확인하려고 하거든? up to bottom 자체를 뭔가 시도를 안하려하는것같아보이는 수준이야

며칠 뒤에는 작은 성공을 계속 더하는 방식 자체를 문제로 설명했다.

create-kr-patch

그리고 뭔가 에이전트들 방식이, 계속 작은 단위만 해결하려고 하거든? 우리는 조직폭력배와 싸워야하는데, 각자를 1:1로 싸워야한다면 결국에는 가장 강한 사람을 못이기면 그냥 의미없어지는것과 마찬가지이니 전체 어떤 한가지 단위를 잘 잡아야하는데, 그것을 계속 그냥 굉장히 작은 단위로 잡으려고 해

8월 6일 Git 기록 eae22e8은 런타임 확인을 파일 수가 아니라 소비 경로로 묶도록 스킬을 고쳤다. 먼저 정적으로 파일·엔트리의 전체 목록을 만들고, 같은 선택 규칙과 로더와 렌더러를 쓰는 항목끼리 묶는다. 그 공통 경로는 대표 사례로 실행해 확인하되, 각 파일이 실제로 그 그룹에 속한다는 사실은 전체 정적 검사로 닫는다. 크기 경계, 별도 압축, 다른 캐시나 렌더러를 쓰는 예외만 따로 실행한다.

“전수”라는 말도 무엇을 보느냐에 따라 달라졌다.

확인할 것맞는 범위
파일·엔트리의 포함 여부, 포인터와 형식, 글리프·공간 수요 전체를 정적으로 검사
같은 로더와 렌더러를 거치는 집단이 실제로 동작하는지 소비 경로별 대표 사례를 실행
크기 경계, 별도 압축, 다른 상태 수명을 가진 항목 예외와 경계 항목을 따로 실행
번역의 의미, 말투와 자연스러움 선언한 번역 범위를 사람이 읽고 검수

사람이 1,100개 파일을 대신 실행하는 것이 해법은 아니었다. 사람이 알려 준 층, 메뉴, 캐릭터, 엔딩과 숨은 모드는 전체 목록이 설명해야 할 기준이 됐다. 에이전트는 그 기준에서 파일과 소비자를 역으로 찾아 분모를 만들고, 빠진 영역과 아직 분류하지 못한 영역을 따로 남겼다.

다음 프로젝트에서 전체 범위를 물을 때는 수치 하나보다 다음 질문이 유용하다.

  • 이 작품에 반드시 있는 층, 장면, 메뉴, 캐릭터, 분기와 엔딩을 현재 목록이 모두 설명하는가?
  • 번역 항목, 글리프 수요, 그래픽 화면과 소비 경로의 분모를 서로 나눠 셌는가?
  • 파일을 어떤 정적 근거로 같은 소비 경로에 묶었는가?
  • 대표 실행 하나가 증명하는 공통 경로와 별도 확인할 예외는 무엇인가?
  • 미확인 대상을 완료 목록이나 제외 목록에 섞지 않고 남겼는가?

원본과 빌드: 작업 폴더의 성공을 다시 만들 수 있는 결과로

조사 중에는 짧은 스크립트와 손으로 고친 산출물이 빠르게 답을 줄 때가 있다. 문제는 그 결과가 최종 빌드의 입력으로 남을 때다. 같은 기능을 두 코드가 따로 만들고, 어제 생성한 파일을 오늘 다시 패치하면 현재 소스만으로 화면의 출처를 설명할 수 없다. 여러 프로젝트의 프롬프트는 특정 언어를 선호한다는 말보다 최종 결과를 만드는 경로를 하나로 닫으라는 요구로 바뀌었다.

단발성 조사는 주 빌드의 두 번째 구현이 될 수 없었다

세가 새턴 마도물어에서는 폰트와 시퀀스 수정이 여러 도구에 흩어지자, 코드베이스로 같은 실험을 계속 실행할 수 있게 하라는 요구가 나왔다.

세가 새턴 마도물어

우선적으로, 코드 리뷰어 4명 (존 카맥, 리누스 토발스, 러스트 프로그래밍 전문가, 어셈블리 프로그래밍 전문가)의 리뷰를 거쳐서, 코드베이스를 리팩토링하자. 테스트 파일도 따로 분리하는 패턴으로 가고. 최종적으로는 모든 덮어쓰는 행위는 감시되고 컨트롤 되어야만 해. 또한, 우리는 최종적으로 코드베이스를 통해서 테스트를 계속 진행해야해. 코드베이스를 통해서 격리 테스트가 진행될 수 있도록 작성하고, 단발적 파이썬 스크립트로 뭔가를 진행하려고 해서 최종적으로 어디서는 되는데 어디서는 안되고를 좀 없애고 싶어.

메가드라이브판에서는 어느 구현이 기준인지 더 짧게 못박았다.

메가드라이브 마도물어 I

Rust가 SoT야. 파이썬이 엉망으로 짜져있는거고. 러스트쪽에 지금 만든것들을 맞춰.

최종 ROM을 만드는 구현이 이미 Rust 쪽에 있었으므로 이를 기준으로 삼았다. Git 이력에는 TTF와 번역에서 ROM을 만드는 빌드(1b0e2c3), 파생 데이터를 다시 만드는 init 명령(c3a17fa), 뒤이어 레거시 스크립트를 제거한 기록(bafeba4)이 이어진다. 조사용 스크립트는 쓸 수 있어도 그 스크립트만 아는 변경을 배포 산출물에 남기지는 않았다.

참고 패치는 단서로 남기고 최종 입력에서 뺐다

게임기어판의 초기 한국어 빌드는 영어 패치 ROM을 먼저 요구했다. 영어판에서 훅과 여유 공간을 찾기는 쉬웠지만, 일본 원본에서 영어판을 거쳐 한국어판으로 온 변경 중 무엇이 필요한지 설명하기 어려웠다.

게임기어 마도물어 I

이제 JP롬 위에 바로 씌울 수 있는 인프라를 만드는 방향으로 가보자. 그사이 어느정도 진전된 다른 자매 프로젝트들 참고해도 좋고

다음 날 Git 이력에는 일본판 원본에서 한국어 렌더러, 재배치 대사와 UI 그래픽을 만드는 변경이 차례로 들어왔다. 영어 패치는 버리지 않고 변경 위치와 구현 후보를 찾는 비교 자료로 남겼다. 달라진 점은 사용자가 준비해야 할 빌드 입력이었다. 참고 자료의 산출물을 다시 패치하는 대신, 확인한 일본판 원본과 프로젝트가 소유한 입력만으로 결과를 만들게 됐다.

따로 성공한 기능은 한 산출물에서 다시 만났다

폰트, 대사, 그래픽과 엔딩이 각자 되는 격리 빌드는 서로의 주소와 글리프 공간을 침범하는지 알려 주지 않는다. 슈퍼 나조 뿌요 2에서 사람은 그래서 한 파일을 요구했다.

슈퍼 나조 뿌요 2

지금 격리빌드야? 전체빌드로 하나 줘봐

PCE-CD판에서는 이미 대사, 그래픽, 자막과 크레딧이 따로 진행되고 있었다. 사람은 통합 결과가 왜 없는지부터 물었다.

PCE-CD 마도물어 I

통합 산출물이 없었던 이유가 뭐지? credits 한번 체크해주고 뭐있는지, 금액 표기는 G라고 안하고 "금" 그냥 쓰면 되고

PCE-CD 마도물어 I

현재 우리 Rust 파이프라인은 Complete해? 현 시점 Rust 코드베이스로만 git을 클론해서 롬을 가져와서 빌드할 수 있어?

PCE-CD 마도물어 I

크레딧·금+숫자 구현하고, 자막 정식 파이프라인에 집어넣고, Rust가 그냥 단 1개의 명령으로 빌드를 완수할 수 있게 해

Git 이력의 431ff52는 번역, 글꼴, 그래픽, 자막, 크레딧과 검사를 한 빌드에 모았고, 33bd4b0은 같은 원본 확인 경로에서 BPS까지 만들게 했다. 7월 18일에는 이 반복 문제가 create-kr-patch에도 반영돼, 완성에 필요한 변경이 하나의 주 빌드에 들어가야 한다는 규칙 d17b119가 추가됐다.

잘 보이는 ROM의 출처도 다시 만들 수 있어야 했다

메가드라이브판에서 화면 문제가 해결된 뒤에는 현재 실행 중인 ROM이 깨끗한 소스에서 나왔는지를 사람이 다시 물었다.

메가드라이브 마도물어 I

또한 롬 빌드가 더티한 상태에서 이루어지면 재현성은 누가 보증해?

메가드라이브 마도물어 I

이번 시점에서야 잘돌아가는걸 알지만 뒤에 모든 트래킹이 정확히 이루어졌고 재현가능함음을 알 수 있어?

그 뒤 Git 이력에는 지정한 일본판 원본과 깨끗한 커밋에서 ROM과 BPS를 다시 만들고 빌드 근거를 묶은 기록이 이어졌다. 화면이 맞는지와 그 화면을 낸 파일의 출처를 각각 확인했다. 작업 폴더에 우연히 남아 있던 ROM이 잘 돌아가도, 같은 원본과 현재 소스로 다시 만들 수 없다면 다음 수정의 기준으로 쓸 수 없다.

사람의 문장 검수는 기술 수용량을 확인한 뒤 본격화했다

원본 기반 통합 빌드는 사람의 검수를 뒤로 미루기 위한 핑계가 아니었다. 이미 다듬은 문장을 글리프 공급이나 디스크 배치 실패 때문에 버리지 않도록 순서를 잡는 일이었다. PS1판에서는 이를 아주 짧게 지시했다.

PS1 와쿠와쿠 뿌요뿌요 던전

우선 프루프리딩보단 빌드 파이프라인부터

PC-98판에서도 앞 장에 인용한 “사람 검수는 글리프와 관련된 확신이 있어야 진행될 수 있다”는 질문이 같은 역할을 했다. 초벌 전체는 글리프 수와 최대 문장 폭을 재는 기술 입력으로 먼저 쓸 수 있다. 말투와 의미를 다듬는 전수 검수는 그 수요가 실제 빌드와 주요 소비 경로에서 받아들여지는지 확인한 뒤 진행한다. 이름, 용어와 문맥처럼 기술 설계 전에 결정해야 할 사항은 먼저 정한다. 기술 설계 전에 필요한 사람 판단까지 미루지는 않았다.

그래서 “됐다”는 말도 하나로 쓰기 어려워졌다.

확인 답할 수 있는 질문 이것만으로 답하지 못하는 질문
격리 PoC 한 조건의 기술적 가능성이 있는가 다른 기능과 함께 들어가도 되는가
원본 기반 통합 빌드 채택한 변경을 한 산출물로 다시 만들 수 있는가 게임이 모든 변경 자산을 실제로 쓰는가
런타임 소비 확인 지정한 상태와 경로에서 게임이 자산을 쓰는가 문장과 화면이 플레이어에게 좋은가
사람 검수 의미, 말투와 화면 선택이 적절한가 원본 조건과 기계 제약이 자동으로 지켜지는가

다음 프로젝트에서 빌드를 요청할 때는 “최종 빌드 하나”보다 입력과 포함 범위를 함께 적는 편이 낫다.

  • 지원할 원본의 리비전, 표현 형식과 해시는 무엇인가?
  • 번역, 글꼴, 그래픽, 코드 훅, 컨테이너 수정과 배포 패치가 한 주 빌드에서 만들어지는가?
  • 수동으로 찾은 변경과 PoC 결과가 어떤 입력과 검사로 주 빌드에 들어왔는가?
  • 작업 중간 ROM이나 선행 패치 산출물이 다음 빌드의 숨은 입력으로 남아 있지 않은가?
  • 배포 패치를 원본에 적용한 결과가 검증한 ROM과 같은가?
  • 현재 실행 증거가 정확히 어느 원본, 커밋과 빌드 결과에 붙는가?

번역 작업: 원문을 지키는 자동화와 문장을 고르는 판단을 나누다

번역 파일은 처음부터 원문 위치와 제어코드를 기억해야 했다

세가 새턴 마도물어의 텍스트 추출 프롬프트에는 이후 공용 스킬로 옮겨 간 요소가 이미 들어 있다.

세가 새턴 마도물어

이제 Next step으로 가보자. 일본어 텍스트 추출. 이 때, 고려해야할 점은 뒤에 갑자기 몰랐던 텍스트가 추가될 걸 대비해 ID로써 원본의 위치를 기억해야한다는점, 추후 번역 1:1이 용이하게 되게 해야한다는점, 번역 후 인코딩때 제어코드가 재인코딩되면 안된다는 점, 그 외 흔히할 수 있는 실수 또는 구조적 실수를 고려해야해.

단순 순번 대신 원본 파일과 위치를 가리키는 식별자를 두고, 원문 바이트와 제어코드를 번역문과 분리했다. 나중에 새 문자열이 발견되더라도 기존 번역의 신원을 잃지 않고, 알 수 없는 토큰을 한국어 문장처럼 바꾸지 않기 위한 구조였다.

번역 검수는 원문·현재 번역·이유·제안을 함께 보게 했다

슈퍼패미컴판의 전수 검수에서는 규칙으로 문장을 일괄 변경하지 말고, 항목별로 판단할 자료를 남기도록 했다.

슈퍼패미컴 마도물어

우선 A'' 번역을 확장하여 번역 검수부터 하는데, 이왕 하는거 "아르르의 말투 통일", "NL 병합 등을 통한 수 줄이기", "다와사 등 직역 표현 검증", "어색하거나 자주 쓰지않거나 특히 어순이 아무 이유없이 틀린 KR 문장" "자주 안쓰는 일본식 한자표현 KR 명사/동사/형용사" "맥락에 맞지 않는 번역" 등을 검증하려고 해. 이를 위해, 전수조사팀을 최대 8명의 팀원으로 아예 꾸렸으면 해. 전체 JSON에 대해서, 반드시 규칙 기반이 아닌 전수조사를 진행하도록 팀원들에게 강조해야하며, 1명씩 각 작업을 맡게 해야해. 따라서, 모든 팀원들은 반드시 리포트 파일을 각 Json마다 translation_review 폴더에 서브 json으로 생산하며, 이 json에는 원문, 현kr, 현재 어색하거나 좋지못한 이유, 제안kr을 포함해야해. 이때, unknown (제어코드 데이터)는 번역하지 않게 해야하고.

이 구조에서 에이전트는 대량으로 후보를 찾고 제안을 만들 수 있다. 사람은 원문과 장면을 읽고 제안을 채택하거나 다시 쓴다. 문장 상태가 raw → in progress → needs review → needs human review → complete로 나뉜 것도 기계 작업과 사람의 승인을 한 상태로 뭉개지 않기 위해서였다.

화면 제약은 문장을 몰래 버리는 이유가 되지 않았다

새턴 와쿠와쿠판에서는 넘치는 문장을 자동으로 자르거나 줄바꿈을 다시 배치하면 빌드는 쉽게 통과할 수 있었다. 사람은 조용히 뜻이 사라지는 기본값을 막았다.

세가 새턴 와쿠와쿠 뿌요뿌요 던전

truncate는 절대로 기본값으로 하지말아줘. 특히나 silent 상황으로 만들지 마

드림캐스트판에서는 공유 타일 충돌을 이유로 번역을 줄이는 타협보다 글리프 공급 구조를 더 조사하게 했다.

드림캐스트 뿌요뿌욘

우선 제 0 Dogma는 "EN 같이"야. 모든 번역은 Complete해야하며, 품질을 양보해서 얻을 수 있는건 하나도 없어. 절대로 공유 타일이 충돌해서 무슨 번역을 재조정한다던가 합리책을 쓰려고 하지 마. MEMORY 중 가장 깊숙한 근본 원칙으로 기록해. 지금 ablation이 충분했어? Spirte idx를 더 키울 수 있게는 못해?

이 원칙은 문장을 절대로 고치지 말라는 뜻이 아니다. 창을 넓히거나 페이지를 나누고 글리프를 늘리는 기술적 선택을 먼저 조사한 뒤, 의미나 말투를 줄여야 할 때는 사람이 그 손실을 보고 결정하라는 뜻으로 정리됐다.

자동화의 경계는 검출과 수정 사이에 놓였다

드림캐스트판의 번역 검사 프롬프트는 이유와 제안은 출력하되 자동으로 원문을 덮지 못하게 했다.

드림캐스트 뿌요뿌욘

우선 "자동 수정"은 절대 넣지 말고, "이유 => 수정 제안"을 출력하게 하자.

PS1판에서 잘못 추출된 경계를 자동 수정으로 덮으려는 흐름이 생겼을 때도 같은 태도가 반복됐다.

PS1 와쿠와쿠 뿌요뿌요 던전

자동수정은 난 믿지 않아. 이미 어떻게 망가졌는지도 못한걸 자동수정으로 계속 덧붙이고싶진 않아.

7월에는 이 판단이 스킬에 들어갈 문장인지 직접 확인했다.

create-kr-patch

혹시 번역에서 "번역의 검출은 자동화 스크립트일 수 있지만 수정은 자동화 스크립트로 이루어져서는 절대 안된다"는 내용이 있나?

8월의 새턴 와쿠와쿠판 전수 검토에서도 같은 구분이 실제 작업 지시로 돌아왔다.

세가 새턴 와쿠와쿠 뿌요뿌요 던전

재배치도 우선 직접 적용할것. 검출은 코드로 하더라도 번역이 코드로 수정되는건 허가못함. 손질은 우선 대기

사람이 오탈자 후보를 손으로 전수 검색할 필요는 없다. 자동화가 전체 범위를 검사하고 원문 위치, 제어코드, 폭과 누락을 지키게 한 뒤, 사람은 실제 문장과 화면에 손실이 생기는 선택을 맡는다.

번역 관련 프롬프트에는 다음 구분을 명시하면 결과를 다시 살피기 쉽다.

  • 원문의 안정 식별자와 보호해야 할 raw byte·제어코드는 무엇인가?
  • 검사는 어떤 오류를 전수로 찾고, 각 항목에 어떤 이유와 수정 제안을 남기는가?
  • 자동화가 직접 바꿔도 되는 것은 객관적으로 동치인 기계 데이터뿐인가?
  • 말투, 뜻, 줄바꿈, 축약과 페이지 추가 중 무엇은 사람의 승인을 기다려야 하는가?
  • 첫 번역, 에이전트 검토, 사람 검토와 빌드 채택 상태가 서로 구분되는가?

글꼴과 의성어는 실제 장면에 맞춰 골랐다

문장이 자연스럽고 글자가 선명해도 화면 전체는 어색할 수 있다. 제목과 본문이 같은 무게로 보이거나, 원본에서 움직이던 의성어가 반듯한 메뉴 글자처럼 서거나, 장식에 불과한 글자까지 바꾸면서 여백이 무너지기도 했다. 사람은 어느 화면인지, 무슨 동작인지, 원본에서 글자가 몇 칸을 쓰고 어떤 방향으로 놓였는지를 프롬프트에 적었다. 이 정보는 곧 구현 조건이 됐다.

한 글꼴로 한국어판 전체를 통일하지 않았다

슈퍼 나조 뿌요 2에서는 게임하기 / 데이터 삭제 메뉴의 커서와 기준선이 어긋나 보이자 새 글꼴을 시험했다.

슈퍼 나조 뿌요 2

지금 내가 보니까 "게임하기 / 데이터 삭제 ..." 이 메뉴가, 미묘하게 커서가 아래에 있거든? 정렬이 좀 안맞는듯하고, 조금 더 깔끔한 글꼴을 쓰고싶은데 galmuri14 14px로 한번 해볼래?

같은 변경이 오버월드의 저장/아이템까지 번지자 사람은 그 화면에는 기존 글꼴을 남기라고 지정했다.

슈퍼 나조 뿌요 2

지금 "저장" "아이템"이 글꼴이 바뀐거지? 이건 기존 글꼴 (neodgm?)을 갔으면 하는데

크기와 여백을 조정한 후보도 실제 화면에서 좋아지지 않으면 채택하지 않았다.

슈퍼 나조 뿌요 2

글리프가 좀 맛이 없어졌네. 그냥 롤백하는게 나을듯

최종 구현은 본문, 퍼즐 조건, 모드 선택 제목과 항목, 첫 실행 안내, 저장·불러오기, 옵션 도움말, 효과음 글자와 에디터의 작은 안내문을 서로 다른 프로필로 나눴다. 같은 인상이 필요한 곳은 한 프로필을 함께 쓰고, 타일 크기와 역할이 다른 곳만 독립적으로 조정했다.

세가 새턴 마도물어의 레벨업 글자도 글꼴 견본만 보고 고르지 않았다. 원본 배경 위에서 획이 묻히자 후보에 빠진 요소를 사람이 짚었다.

세가 새턴 마도물어

만든게 전반적으로 윤곽선 개념 (스프라이트와 유사한 색으로 가독성 나오는) 이 빠졌네. 글꼴 크기는 12-16으로 가자

후보를 다시 만들 때는 12~16픽셀, 윤곽선과 자간을 한꺼번에 비교했다. 실제 배경에서 제목과 본문이 제 역할로 읽히는지를 사람이 골랐고, 코드는 그 선택을 화면별 설정으로 보존했다.

의성어는 읽는 말이면서 움직이는 그림이었다

슈퍼 나조 뿌요 2의 스토리에는 대사 데이터가 아니라 스프라이트로 그린 ガッパチ가 있었다. 첫 장면이 음식을 먹는 동작임을 사람이 알려 주면서 ガッ의 한국어는 음역이 아니라 덥석으로 정해졌다.

슈퍼 나조 뿌요 2

덥석으로 하자. 우선은 분석을 해둬. 의성어 장면이 하나 더 나올거라서

パチ는 원본부터 반시계 방향으로 기울어 있었다. 한국어를 넣을 때도 그 동세를 버리지 않았다.

슈퍼 나조 뿌요 2

이렇게 진행해보자. 이 때 짝의 경우에는 정방향이면 안되고 살짝 기울어야하거든 (파치가 지금 반시계로 30도정도 돌아있음)

첫 후보는 외곽선 때문에 이 뭉쳐 깨진 타일처럼 보였다. 사람은 원본이 두 글자로 읽힌다는 점까지 들어 크기를 다시 지정했다.

슈퍼 나조 뿌요 2

사실 지금 문제가 "짝"이 짝처럼 안보이거든. ㅉ 글자가 그냥 붙어서 거의 그래픽 글리치 덩어리처럼 보이는 수준이라서. 짝은 사이즈 더 키워야할듯 (애초에 일본어로도 2글자였고)

구현에서는 의 간격을 좁히고, 을 키운 뒤 약 30도 기울였다. 원본 오브젝트의 반복도 그대로 두어 화면에서는 짝짝이 된다. 먹는 동작, 두 인물의 박수, 글자의 반복과 기울기라는 장면 정보가 최종 단어와 그래픽 배치를 함께 결정했다.

모든 비한국어 요소를 바꾸지는 않았다

화면에 일본어 코드가 있다고 모두 문장은 아니었다. 세가 새턴 마도물어의 OCR을 시작할 때부터 화살표와 뿌요 모양을 글자 후보에서 분리하라는 설명이 있었다.

세가 새턴 마도물어

글자가 아니라는 것은, 화살표나, "뿌요" 모양 등 캐릭터성 모양 등도 포함되있을 수 있다는거야

슈퍼 나조 뿌요 2의 결과 화면에서는 영문 LEVEL을 이미 읽을 수 있었고, 뒤의 일본어 べつの만 한국어에 걸렸다.

슈퍼 나조 뿌요 2

현재 화면에 "레벨별" 보임

LEVEL은 번역 필요없고 "별"만

최종 화면도 LEVEL별 HI-SCORE처럼 영문 표시는 유지하고 일본어 세 칸을 과 공백으로 바꿨다. 드림캐스트판의 규칙 화면에서는 반대 이유로 일본어 장식을 남겼다. 별 그림 위의 한국어가 짧아져 여백이 크게 보였고, 그 글자가 플레이에 필요한 정보를 더 주지도 않았다.

드림캐스트 뿌요뿌욘

지금 큰 문제가 있는게, JP는 RULE1에서 폭발/충돌의 별 이미지 위에 글자가 있는데, 한국어는 JP랑 글자 크기가 다르니까 횡하게 빈공간이 신경쓰이게 보여. 그냥 Subtitle로 지정했던 저 글자들은 KR을 쓰지말자

셋의 이유는 달랐다. 첫 사례는 애초에 문자가 아니었고, 둘째는 이미 기능하는 영문과 한국어를 한 화면에서 조합했으며, 셋째는 장식 교체가 정보는 늘리지 않고 구도만 해쳤다. 사람은 화면 요소가 전달하는 정보와 역할을 먼저 분류한 뒤 무엇을 번역할지 정했다.

화면 글자와 그래픽을 맡길 때는 다음 정보를 프롬프트에 함께 넣는 편이 좋았다.

  • 이 글자는 본문, 제목, 작은 안내문, 효과음과 장식 중 무엇인가?
  • 같은 글꼴을 유지해야 할 화면과 별도 후보를 비교할 화면은 어디인가?
  • 실제 배경에서 글자 크기, 기준선, 여백, 윤곽선과 자간이 어떻게 보여야 하는가?
  • 의성어가 나타나는 동작, 반복 횟수, 원본의 각도와 셀 배치는 무엇인가?
  • 남아 있는 비한국어 요소가 번역할 정보인지, 기호·고유 표기·장식인지 구분했는가?
  • 바꾸지 않는다면 기술적 한계가 아니라 화면의 역할을 근거로 설명할 수 있는가?

재사용: 결과물을 가져오기보다 검증할 방법을 가져오다

선행 프로젝트는 강한 단서였지만 대상 게임의 사실은 아니었다

2월 슈퍼 나조 뿌요 2를 조사할 때 같은 제작사의 프로젝트 코드를 참고하되, 그 구조에 맞춰 결론을 끼워 넣지 말라는 프롬프트가 먼저 나왔다.

슈퍼 나조 뿌요 2

지금부터 역공학을 본격적으로 시작해보자. 아마 컴파일사가 컨벤션에 아주 강한 변화를 주진 않았을거라고 봐. JP 인코딩 테이블 등은 변화했을 수 있겠지만. 한번 madou_sample 쪽 폴더의 코드들을 참조해도 되지만, 너무 치우치지는 말도록 해. 플랜을 세우고 여러 가설들을 세워서, 객관적인 분석 사항들을 문서화해봐.

이 원칙은 선행 작업을 버리라는 말과 다르다. 어디를 먼저 볼지, 어떤 실패를 예상할지, 어떤 검사를 빌드에 둘지는 재사용할 수 있다. 주소, 빈 공간, 인코딩 폭, 글리프 수와 소비 경로는 새 원본에서 다시 확인해야 한다.

영어 패치의 레이아웃도 한국어의 정답은 아니었다

게임기어판은 영어 패치에서 많은 구조를 찾았지만, 영어에 맞춘 좁은 줄 간격이 한국어에는 맞지 않았다.

게임기어 마도물어 I

우선 이게 밀린게 문제가 아니야. 좀 재밌는게, EN이랑 JP랑 줄 시스템이 좀 달라서 발생하는 문제도 좀 있는데. 우리가 EN식 폰트 시스템을 쓰면 안되고 JP식을 써야할 것 같은데. EN은 eng가 7x7 이하에서도 가독성이 나오니 줄간격을 거의 없애도 되었는데, 원본은 애초에 줄간격을 크게 해뒀어. 3줄 내로 전부 끝나게. 이게 오히려 EN이면 가독성이 낮아지는 요소니까 여기서 바꾼거고. KR은 굳이 따지면 JP에 더 가까워

선행 패치는 주소와 변경 지점을 찾는 비교 자료로 유용했다. 다만 선행 패치가 바꾼 화면 밀도, 폰트 높이, 줄 수와 커서 위치까지 물려받으면 한국어에는 새 문제가 될 수 있었다. 이 경험은 “영어판을 베이스로 쓰는가”보다 “영어판에서 무엇을 빌렸고, 일본 원본과 어떤 차이를 다시 검사했는가”를 묻게 했다.

공용 방법도 특정 도구 이름에 묶지 않았다

스킬을 다듬을 때는 emucap이나 특정 에뮬레이터를 반드시 쓰라는 식으로 일반화하지 않도록 했다.

create-kr-patch

그리고 이 스킬의 철학 관점에서도 생각해야해. emucap이니 Mesen GG니 하는것들을 배제하는게 맞아. 도구에 일반화되선 안되니까

필요한 것은 메모리 읽기, 상태 재현, 쓰기 추적 같은 기능과 거기서 얻은 증거다. 지금 환경에서 emucap이 그 능력을 가장 잘 제공할 수는 있어도, 방법론 자체가 한 도구의 명령어나 경로를 정답으로 삼으면 다른 플랫폼에서 바로 낡는다.

이후 스킬의 플랫폼 문서가 실제 프로젝트와 어긋날 때도 사례를 그대로 공용 규칙으로 덧붙이지 않았다. PC-98의 HDM 크기, 새턴의 VDP1·VDP2 텍스트 경로, 드림캐스트의 PVR과 아카이브 내 raw 폰트처럼 대상마다 갈린 사실은 적용 조건과 근거를 붙였다. 한 게임에서 확인한 수치는 사례로 남기고, 여러 대상에 적용할 수 있는 판정 질문만 공용 전략으로 올렸다.

재사용을 요청할 때는 “자매 프로젝트처럼 해 달라”보다 다음과 같이 범위를 나누는 편이 안전하다.

  • 선행 프로젝트에서 가져올 것은 구현, 실패 사례, 검사 방식 중 무엇인가?
  • 새 대상의 원본 해시와 구조에서 다시 확인할 주소·수치·포맷은 무엇인가?
  • 영어 패치나 다른 기종이 바꾼 레이아웃을 한국어에도 유지할 근거가 있는가?
  • 사용한 도구가 아니라 필요한 관찰 능력과 합격 조건을 설명할 수 있는가?
  • 한 타이틀의 사례를 공용 원칙으로 옮길 만큼 반복된 근거가 있는가?

스킬: 프로젝트에서 반복된 철학이 공용 원칙이 되기까지

스킬이 생기기 전부터 원칙은 프롬프트에 있었다

create-kr-patch 스킬의 첫 패키징은 Git 기록상 6월 17일이다. 그러나 스킬의 내용이 그날 새로 생긴 것은 아니다. 앞선 프로젝트 프롬프트에 흩어져 있던 판단이 먼저 있었다.

스킬 이전의 반복된 판단 앞선 프롬프트에서 보인 형태 뒤에 스킬로 정리된 내용
원문과 기계 데이터를 잃지 않는다 2월 새턴판의 원본 위치 ID와 제어코드 보존 번역 데이터와 보호 메타데이터의 분리
쓰기 범위와 원본 조건을 빌드에서 검사한다 2월 슈퍼패미컴판의 TrackedRom과 Expect Expected Write와 전체 diff 검사
화면을 보지 않고 완료라고 하지 않는다 3월 “HITL 전에 해결되었다고 쓰지 말라” 정적 검증과 런타임 소비 증거의 분리
기술적 한계를 번역 품질 저하로 먼저 갚지 않는다 3월 “번역을 포기해서 안정화하는 건 마지막” 공급 확장 뒤 의미 손실은 사람 승인
자동 검출과 문장 수정은 다르다 3월의 “이유 → 수정 제안” 객관적 실패만 자동화하고 문장 선택은 사람에게 둠
한 글자 성공이 전체 가능성을 뜻하지 않는다 여러 프로젝트의 글리프·재배치 실패 완성에 중요한 어려운 조건을 PoC로 삼음

스킬은 에이전트가 실수하니 나중에 붙인 벌점표가 아니다. 사람이 여러 게임에서 반복해 온 작업 철학을 다른 프로젝트에서도 다시 쓰도록 정리했다.

중심 철학은 사람을 반복 조작에서 빼고 판단에 남기는 것이었다

6월 29일 프롬프트는 스킬과 emucap이 공유할 방향을 직접 설명한다.

create-kr-patch

내가 가장 중요시여기는 것은 바로 "사람의 개입의 최소화"와 "상황 맞춤형"이야. AI(LLM)의 장점은 휴리스틱한 상황에 능동적인 대처가 가능하다는 것인데, 사람이 휴리스틱한 대처를 하는 것이 안좋은 상황이야. 이때문에 GUI를 배제하고 있는거고. 또한, 패치 행위라는 것이 플레이어의 경험을 결정한다는 사실이 기초적인 철학이며, AI 기반 패치의 단점인 한글 패치를 최대한 "Nothing bad happen"방향으로 끌고 가도록, 최대한 재현성과 문서화를 기반으로, Agent-Independent하게 AI 홀로 모든 도구를 찾거나 개발하며 진행할 수 있도록 하는 것이 목표인거야

여기서 “사람의 개입 최소화”는 사람의 취향과 게임 지식을 제거한다는 뜻이 아니다. 파일을 하나씩 열고, 디버거 값을 옮기고, 이미 정해진 오류를 손으로 찾는 반복을 줄이자는 뜻이다. 에이전트가 상황에 맞는 도구를 고르고 조사하되, 플레이 경험을 바꾸는 선택은 사람이 할 수 있게 증거와 후보를 내놓는 방향이다.

스킬은 모든 작업 순서를 고정하지 않도록 계속 다듬었다

7월에는 무엇을 공용 규칙으로 강제할지 범위를 좁혔다.

create-kr-patch

이 스킬의 철학은 무조건 "이렇게 되면 이렇게 해야만 한다"는 빌드 단계 등에서만 강제하려고 하거든? 그 외에것들은 에이전트가 자유롭게 판정할 수 있다고 보이는데, 실제로 어떤 것이 그렇게되면 strategy에 들어갈만해보여?

이 질문에 따라 특정 언어, 라이브러리, 에뮬레이터나 고정된 조사 순서보다 조건부 실패 기준이 남았다. 예를 들어 원본과 다른 값을 기대하지 않은 곳에 썼거나, 필요한 문자가 매핑되지 않았거나, 제어코드가 바뀌었다면 빌드는 실패해야 한다. 어느 디스어셈블러를 쓰고 저장 경로부터 볼지 소비 경로부터 볼지는 대상의 증거에 따라 에이전트가 고른다.

실제 프로젝트의 반례가 스킬을 계속 고쳤다

스킬이 생긴 뒤에도 프로젝트는 스킬을 적용받기만 하지 않았다. 새 게임에서 맞지 않는 부분을 다시 스킬 쪽으로 돌려보냈다.

  • 게임기어판은 영어 패치의 줄 간격을 그대로 물려받는 위험을 드러냈다.
  • PCE-CD판은 선행 도구의 2048바이트 오프셋과 raw 2352바이트 섹터의 차이, 원본 라운드트립의 필요를 보여 줬다.
  • PC-98판은 디스크 저장 공간, 인코딩 공간과 런타임 외자 슬롯이 서로 다른 상한임을 보여 줬다.
  • 다른 새턴 타이틀에서는 한 프로젝트의 VDP2 텍스트 방식이 VDP1 스프라이트 텍스트에 그대로 적용되지 않았다.
  • 다른 드림캐스트 타이틀에서는 뿌요뿌욘의 PVR 사례와 달리, 게임 아카이브 속 raw 글리프 배열이 본문 렌더 경로였다.

이 사례들은 “게임기어에서는 항상 이렇게 한다” 같은 새 명령으로 들어가지 않았다. 먼저 어떤 대상에서 확인됐는지와 다른 대상에 옮길 수 없는 범위를 적고, 공통 문서에는 렌더 경로와 저장·적재·소비를 따로 확인하라는 질문만 남겼다.

스킬도 적용 결과를 보고 다시 범위를 고쳤다

7월에는 자동화가 선택까지 대신하지 않게 하는 원칙을 더 분명히 했다.

create-kr-patch

난 자동화가 될때 좋은 부분도 있고 나쁜 부분도 있다고 보거든? 이 스킬의 철학에서부터 결국 가야하는데, 기본적으로 반드시 실패해야만 하는 것인것만 자동으로 되야하고, 선택의 요소는 자동이 되서는 안된다는 철학을 가졌다는것

8월에는 앞의 전체 범위 장에서 본 1,100개 파일 문제가 새 반례가 됐다. “런타임 증거가 중요하다”를 “모든 파일을 한 번씩 플레이한다”로 읽자 오히려 전체 구조를 보지 못했다. 이에 따라 스킬은 전체 목록을 정적으로 닫고, 같은 소비 경로는 대표·경계 사례로 실행하며, 예외만 따로 확인하도록 다시 고쳐졌다.

스킬은 다음과 같은 순환을 거쳐 바뀌었다.

  1. 게임 프로젝트에서 같은 판단이 반복된다.
  2. 여러 대상에도 필요한 조건만 공용 스킬로 옮긴다.
  3. 새 프로젝트가 과한 일반화나 빠진 경계를 드러낸다.
  4. 사례의 적용 범위를 남기고 공용 원칙을 다시 좁히거나 보강한다.

스킬을 읽는 것만으로 대상 게임의 답이 나오지는 않는다. 스킬은 사람이 매번 되풀이한 금지선과 증거 조건을 잊지 않게 한다. 프로젝트별 프롬프트는 그 안에 현재 게임의 장면, 원본, 난도와 취향을 채운다.

같은 시기에도 여러 흐름이 겹쳐 움직였다

앞의 흐름을 날짜순으로 다시 놓으면 한 단계씩 차례로 발전한 이야기가 아니라는 점이 더 분명하다. 어떤 프로젝트는 쓰기 안전성이 먼저 필요했고, 다른 프로젝트는 전체 번역 수요나 게임의 진행 순서를 먼저 알아야 했다.

시기 대화에서 달라진 질문 프로젝트를 건너 이어진 일
2월 “한글이 나오는가”와 함께 “전체 뱅크를 찾았는가”, “원본의 어느 위치인가”, “예상한 바이트만 덮는가”를 물었다. 원문 위치 ID, Rust 주 빌드, TrackedRom과 Expected Write가 각각 다른 프로젝트에서 생겼다.
3~4월 문장 검수보다 전체 디스크 빌드를 먼저 돌리고, 화면을 본 뒤에는 누가 언제 다시 덮는지 추적했다. 추출량도 작품 분량과 비교했다. PS1 전체 빌드, 새턴 캐시·적재 조사, 슈퍼패미컴 상태 수명 문제, PC-98 MENUDAT 분모 교정이 병행됐다.
6월 사람이 옮겨 적던 HITL을 도구로 다루려 했고, 한 글자 PoC가 최종 수요를 과장해 대표한다는 문제를 다시 봤다. emucap이 시작됐고, 완성을 막는 조건을 PoC로 삼으라는 원칙이 create-kr-patch에 들어갔다.
7월 “일본 원본에서 다시 만들 수 있는가”, “전체 초벌 수요가 들어가는가”, “실제 소비까지 이어지는가”와 함께 “이 글자는 어느 화면 역할과 동작을 맡는가”를 물었다. 게임기어판의 JP 직결 빌드, PC-98·슈퍼 뿌요뿌요 2 전체 수요 시험, PCE-CD 한 명령 통합 빌드와 슈퍼 나조 뿌요 2의 화면별 글꼴·의성어 작업이 이어졌다.
8월 프로젝트별 ISA와 검사를 공용화하는 한편, 1,100개 파일을 1,100번 실행하는 과한 적용도 고쳤다. 공용 typed ISA가 생겼고, 전체 목록은 정적으로 닫되 실행 확인은 소비 경로별로 묶는 원칙이 추가됐다.

이 표의 행은 성숙도 등급이 아니다. 2월의 Expected Write가 7월의 한 명령 빌드보다 덜 발전한 방법인 것도 아니고, 6월의 emucap이 수동 HITL을 쓸모없게 만든 것도 아니다. 서로 다른 문제를 푸는 장치가 필요한 시점에 생겼고, 뒤의 프로젝트가 앞의 원칙을 새 조건에서 다시 시험했다.

시기를 가로질러 공통으로 바뀐 것은 사람에게 묻는 내용이었다. 처음에는 실행 결과와 주소를 많이 받았다. 점차 사람이 아는 작품의 전체 구조, 반드시 유지할 플레이 경험, 번역에서 받아들일 수 있는 손실과 정상 장면을 먼저 받고, 주소 탐색·전체 파일 검사·재현 빌드는 도구와 에이전트가 맡게 됐다.

이 변화 속에서 사람이 한 일

대화를 통틀어 사람의 역할을 한두 개 직함으로 고정하기는 어렵다. 기술 문제가 달라질 때마다 개입하는 지점도 달랐다. 다만 사람이 계속 붙잡은 것은 직접 코드를 얼마나 쓰느냐보다 “무엇을 게임으로 받아들일 것인가”였다.

작품의 실제 크기와 빠진 장면을 알려 줬다

자동 추출이 5층까지만 보였을 때 이 게임은 11층과 지하 4층까지 있다고 알려 줬고, PC-98판에서 스토리 460개는 너무 적다고 지적했다. 두 번째 실패에서만 나오는 힌트, 특정 주문, 캐릭터 선택 뒤 던전처럼 자동화가 모르는 게임 상태도 사람이 제공했다. 이런 정보는 주소 정답이 아니라 조사해야 할 모집단과 소비 경로를 바꾸는 입력이었다.

게임 지식은 번역표 바깥의 정답지였다

자연스러운 문장이 항상 맞는 문장은 아니었다. 메가드라이브판에서는 영어판이 비슷한 절임을 한 단어로 뭉개도, 실제 게임에는 회복량이 다른 두 아이템이 따로 있었다.

메가드라이브 마도물어 I

후쿠진즈케는 락교가 아니거든. 좀 심각한 차이인데? 락교는 그냥 일본어로도 락교라 되있지않아? 굳이 따지면 한국에서는 "행운절임"으로 번역됬던건데, 후쿠진즈케를 그대로 쓰기로 하지 않았어? 이 게임에는 락교라는 아이템도 (체력 최소회복), 후쿠진즈케라는 아이템도 (체력 중 회복) 둘 다 존재해. 아이템 혼동이 나면 큰일나.

PCE-CD판에서는 화면의 번역보다 일본어 음성이 먼저 오역을 드러냈다.

PCE-CD 마도물어 I

또한 "정말 미안하구나 하지만" 이쪽은 센세와 쟌넨데시타 뭐 이런 JP 음성이 들리는데, 선생님은 정말 아쉽구나 이런거 아니야?

반대로 슈퍼 나조 뿌요 2의 왼오오오왼은 문장처럼 읽으면 지나친 축약 같지만 실제 퍼즐 답과 맞았다.

슈퍼 나조 뿌요 2

왼오오오왼 그 자체는 가능성은 있어. 이유는 저 힌트가 맞긴하거든 (왼-오-오-오-왼으로 배치해야한다는거)

세 프롬프트가 가져온 근거는 각각 아이템 효과, 들리는 음성과 퍼즐 규칙이었다. 사람은 마음에 드는 표현을 고른 데 그치지 않고, 번역 파일 밖에서 그 문장이 맞는지 판정할 자료를 제공했다. 에이전트는 그 지점을 원문 위치와 같은 항목의 다른 출현 장면으로 넓혀 확인했다. 이때 사람의 역할은 모든 문장을 직접 쓰는 것이 아니라, 그럴듯한 오답과 작품 안에서 실제로 성립하는 말을 가르는 데 있었다.

기술적 우회가 플레이 경험을 바꾸면 멈췄다

캐릭터별 ROM 세 개가 각각 실행돼도 한 게임으로 배포할 수 없다고 판단했고, 공간이 부족하다는 이유로 번역을 줄이기 전에 글리프 공급과 페이지 구조를 더 조사하게 했다. 사람이 한 일은 어려운 구현을 대신 푸는 것이 아니라, 기술적으로 편한 결과가 애초 목표를 바꾸는 순간을 알아보는 것이었다.

반복되는 실패에서 공통 금지선을 뽑았다

한 번의 충돌을 고치는 데서 멈추지 않고 모든 쓰기를 추적하게 했고, 예상한 원본에만 쓰도록 Expected Write를 붙였다. 수동 HITL이 반복되자 관찰 도구를 만들었고, 한 글자 PoC가 반복되자 가장 어려운 완성 조건과 통합 빌드를 스킬에 넣었다. 사람의 철학이 스킬로 갔다는 것은 이런 식으로 국소 수정이 공용 경계로 바뀐 과정을 뜻한다.

문장과 화면의 선택은 끝까지 사람이 했다

자동화는 누락, 폭, 제어코드, 원문 불일치와 수정 후보를 전체에서 찾았다. 어떤 말투가 인물에게 맞는지, 뜻을 줄일지 페이지를 늘릴지, 한글 그래픽이 원작 화면과 어울리는지는 사람이 원문과 실제 장면을 보고 정했다. 메뉴마다 같은 글꼴을 쓸지, 의성어를 어느 방향으로 기울일지, 읽을 수 있는 영문이나 장식 글자를 그대로 둘지도 이 판단에 포함됐다. 가능한 답이 여러 개일 때 플레이 경험을 고르는 일은 끝까지 사람에게 남았다.

반복 작업은 사람에게 남기지 않았다

사람이 1,100개 파일을 하나씩 실행하거나, 매번 메모리 값을 답변 파일에 옮기거나, 어떤 주소를 늘려야 하는지 대신 역공학하는 것은 목표가 아니었다. 그런 반복은 추출기, 빌드 검사, typed ISA, Expected Write와 emucap으로 옮겼다. 사람에게 질문할 때는 기술 조사를 대신해 달라고 하기보다 다음처럼 선택의 근거가 필요한 지점을 묻는 편이 맞았다.

상황 자동화가 먼저 준비할 것 사람에게 물을 것
추출량이 작품 규모와 맞지 않음 파일·테이블·소비자별 전체 후보와 누락 가능성 게임에 반드시 있어야 하는 장면과 범위
화면이 특정 상태에서만 깨짐 재현 입력, 원본·패치 비교, 첫 차이와 캡처 기록 그 상태의 의미와 정상 장면
자산이 빌드에는 있지만 화면에 안 나옴 선택·적재·상주·소비 중 처음 끊긴 연결 캐릭터 전환과 재진입 등 상태가 바뀌는 지점
작업 폴더의 ROM만 정상임 원본 해시, 입력 목록, 깨끗한 주 빌드와 결과 비교 최종 결과에 반드시 포함할 기능과 자산
글리프나 창 공간이 부족함 확장·동적 적재·페이지 분할의 가능성과 비용 의미나 말투 손실을 받아들일지 여부
번역 후보가 여러 개임 원문, 현재 번역, 문맥, 길이와 제안 이유 인물 말투와 최종 표현
문장은 자연스럽지만 게임과 맞지 않음 같은 항목의 사용 장면, 효과, 음성, 화자와 퍼즐 결과 작품 지식과 플레이 기억으로 어느 해석이 성립하는지
한글 그래픽이 읽히지만 장면과 어울리지 않음 같은 배경의 글꼴·크기·윤곽·각도 후보와 원본 배치 화면별 위계, 동세와 바꾸지 않을 요소
선행 패치를 재사용하려 함 원본 대비 변경 목록과 대상 게임 재검증 어떤 화면 경험을 유지할지
원칙을 스킬로 올리려 함 여러 프로젝트의 반복 근거와 전이 한계 공통 금지선인지 국소 사례인지

다음 프로젝트에서 쓸 수 있는 프롬프트의 형태

이 기록에서 유용한 프롬프트는 구현 방법을 미리 단정한 문장보다, 사람이 알고 있는 게임의 조건과 자동화가 증명해야 할 범위를 함께 주는 문장이었다. 상황별로 압축하면 다음과 같다.

조사를 시작할 때

이 게임에는 적어도 [층·장면·모드·캐릭터]가 있다. 현재 추출 결과가 그 분량과 맞는지 먼저 모집단을 세워 확인해라. 선행 패치는 단서로만 쓰고, 원본에서 포맷·주소·소비 경로를 다시 검증해라.

전체 범위를 셀 때

실행 중 발견한 파일을 하나씩 더하지 말고, 화면과 기능의 소비자에서 거꾸로 파일·엔트리의 전체 목록을 만들어라. 같은 선택 규칙과 로더와 렌더러를 쓰는 집단을 나누고, 공통 경로는 대표 사례로 실행하되 각 항목의 소속은 전수 정적 검사로 확인해라. 예외와 미확인 영역은 따로 남겨라.

ROM이나 디스크 쓰기를 추가할 때

최종 빌드의 모든 쓰기를 추적 경로로 모아라. 각 쓰기에 기대하는 원본 바이트나 빈 공간 조건을 선언하고, 기능끼리 겹치거나 미추적 변경이 생기면 실패하게 해라. 실행 코드를 넣는다면 대상 CPU의 typed ISA로 생성하고 다시 해석해 확인해라.

PoC를 정할 때

한글 한 글자가 보이는지보다 완성된 패치에서 가장 어려운 필수 조건이 무엇인지 먼저 찾아라. 그 조건의 실제 규모로 시험하고, 실패하면 바꿀 설계와 성공 뒤에도 남는 위험을 적어라. 이번 PoC가 증명하지 못한 범위도 함께 남겨라.

원본에서 통합 빌드를 만들 때

[원본 리비전·형식·해시]와 프로젝트가 소유한 입력만으로 빌드해라. 번역, 글꼴, 그래픽, 코드 훅과 컨테이너 변경을 한 주 빌드에 넣고, 중간 ROM이나 단발성 스크립트 결과를 숨은 입력으로 쓰지 마라. 같은 경로에서 배포 패치를 만들고, 이를 원본에 적용한 결과가 검증한 ROM과 같은지 확인해라.

실행 장면을 확인할 때

[시작 상태]에서 [입력 순서]로 [문제 장면]을 재현해라. JP와 KR의 원본 해시, 빌드, 상태와 입력을 맞춘 뒤 첫 차이를 기록하고, 화면·메모리·이벤트를 같은 실험 기록에 묶어라. 내가 판단할 것은 [장면의 의미·정상 동작·화면 선택]이다.

런타임 자산의 연결을 확인할 때

빌드에 들어간 [글꼴·문장·그래픽]이 어떤 표와 분기로 선택되고, 어디로 적재·변환되며, 어느 RAM·VRAM에서 얼마 동안 남고, 어떤 렌더러가 읽는지 이어서 보여 줘. [캐릭터 전환·재진입·두 번째 로드]가 수명을 바꾸는지 확인하고, 한 사례가 증명하는 소비 경로의 범위를 적어라.

번역을 검수할 때

원본 위치, 원문, 제어코드, 현재 번역과 상태를 보존해라. 코드는 누락·폭·매핑·어색한 후보를 전수 검출하고 이유와 제안을 내되 번역문을 자동으로 고치지 마라. 말투·축약·줄바꿈·페이지 분할은 원문과 실제 화면을 본 뒤 내가 선택한다.

문장은 자연스럽지만 게임 내용과 맞지 않을 때

[아이템 A와 B]는 실제로 별도 항목이고 효과도 다르다. [이 장면의 화자·음성·퍼즐 답]은 [관찰한 내용]이어야 한다. 현재 번역이 자연스럽다는 이유로 통과시키지 말고, 같은 이름이 나온 모든 위치와 실제 사용 결과를 원문에 맞춰 보여 줘. 수정할 표현은 그 비교를 본 뒤 정한다.

화면 글자와 의성어를 고를 때

이 요소가 본문, 제목, 작은 안내문, 효과음과 장식 중 무엇인지 먼저 구분해라. 실제 배경에서 글꼴·크기·윤곽·자간 후보를 비교하고, 의성어라면 장면의 동작, 반복 횟수, 원본 각도와 셀 배치를 함께 맞춰라. 읽을 수 있는 영문이나 비문자 장식은 무조건 번역하지 말고 바꿀 이유와 남길 이유를 화면에서 보여 줘. 최종 선택은 내가 한다.

프로젝트 경험을 스킬로 옮길 때

이번 결론이 이 게임의 주소·도구·수치에만 해당하는지, 여러 프로젝트에서 반복된 조건인지 구분해라. 공용 스킬에는 “이 조건이면 반드시 실패하거나 확인해야 한다”는 경계만 올리고, 대상별 사례에는 관찰 범위와 다른 게임으로 옮길 수 없는 부분을 남겨라.

이 문장들은 그대로 복사하는 주문보다 빈칸을 채우는 골격에 가깝다. 사람이 게임의 범위와 선택 기준을 주면, 에이전트가 거기에 맞는 조사와 도구를 고른다. 2월부터 8월까지 반복 조작과 기술적 전수 작업은 시스템으로 옮겨 갔고, 사람만이 제공할 수 있는 게임 지식과 선택 기준은 프롬프트에 더 구체적으로 남았다.