엔진가이드자주 묻는 질문PatreonDiscord다운로드
로그인
RuneTranslate · 일본 게임을 처음부터 끝까지 번역
엔진가이드비교이미지 텍스트세이브 편집기치트 모드자주 묻는 질문다운로드PatreonDiscordYouTube개인정보 처리방침이용약관문의
모든 글
unreal · guides · engine · localization

Unreal Engine 게임을 번역하는 방법

2026년 8월 18일·9 분 읽기

Unreal 게임은 텍스트를 .pak이나 IoStore 컨테이너 안의 컴파일된 .locres 테이블에 담아 배포합니다. 그것을 읽는 방법과, 왜 결과물이 다시 빌드한 게임이 아니라 아주 작은 오버라이드 pak인지 설명합니다.

Unreal Engine 게임은 드라이브에 있는 것 중 번역하기 가장 어려워 보입니다. data 폴더도, 스크립트 파일도, 열어 볼 .json도 없습니다 — 실행 파일 하나, 거대한 .pak 파일 한두 개가 든 Content/Paks 디렉터리, 그리고 어쩌면 .utoc/.ucas 컨테이너 한 쌍이 전부입니다. 좋은 소식은, 여러분이 실제로 원하는 텍스트가 대개 설계상 그 파일들 안에 숨겨져 있는 것은 아니라는 점입니다. Unreal에는 일급 현지화 시스템이 있고 출시된 게임 대부분이 그것을 씁니다. 여러분이 할 일은 테이블을 찾아 문자열을 바꾸고, 원본보다 우선하는 작은 파일 하나를 엔진에 건네주는 것입니다.

바로 그 마지막 대목이, 한번 이해하고 나면 Unreal을 편안한 엔진으로 만듭니다. 60 GB짜리 게임을 다시 빌드하지 않습니다. 킬로바이트 단위로 재는 오버라이드 아카이브를 만들어 원본 옆에 떨궈 놓습니다.

단계로 들어가기 전에 하나: RuneTranslate의 Unreal 지원은 최선의 노력이고 RPG Maker나 Ren'Py 같은 엔진보다 새롭습니다. 실제 UE4 타이틀에서 플레이 가능함이 확인되었지만, 형식의 표면이 워낙 넓고 스튜디오마다 패키징 방식이 다릅니다. 긴 번역 실행에 들어가기 전에 내보낸 빌드를 인게임에서 검증하세요.

Unreal 게임이 실제로 배포하는 것

Unreal은 플레이어에게 보이는 텍스트를 `.locres` 파일에 담습니다 — FTextLocalizationResource의 컴파일된 형태입니다. 컬처마다 하나씩 있고, <Game>/Content/Localization/Game/ja/Game.locres 같은 경로에 놓이며, en, zh-Hans를 비롯해 스튜디오가 배포한 것들이 형제로 함께 있습니다. 번역이 하나도 없는 게임이라도 보통은 원래 작성된 컬처용으로 하나는 가지고 있습니다.

.locres는 텍스트 파일도 아니고 단순한 키/값 목록도 아닙니다. 네임스페이스로 조직된 바이너리 테이블이고, 각 네임스페이스가 키를 담고, 각 키가 문자열 하나를 가리킵니다. 최신 버전에서 네임스페이스와 키는 읽을 수 있는 이름이 아니라 해시로 저장되며(버전 2는 CRC32, 버전 3은 UTF-16에 대한 CityHash64), 문자열 자체는 참조 횟수를 가진 공유·중복 제거 조회 테이블에 들어 있습니다. 런타임은 영어 텍스트로 문자열을 찾는 일이 없습니다 — 빌드 시점에 게임의 블루프린트와 C++ 안으로 컴파일되어 들어간 그 네임스페이스/키 쌍으로 찾습니다.

그 구조 때문에, 이 파일을 안전하게 편집하는 방법은 하나뿐입니다. RuneTranslate는 모든 네임스페이스 해시, 키 해시, 원본 문자열 해시를 바이트 단위 그대로 보존하고 값만 바꾼 뒤, 중복 제거된 문자열 테이블과 그 참조 횟수를 다시 만듭니다. 무엇도 해시를 다시 계산하지 않으므로, 게임이 찾지 못하는 키가 만들어질 수 없습니다. 번역은 원본보다 길어도 짧아도 상관없습니다.

이 .locres 파일들은 그다음 .pak 아카이브로 패킹됩니다 — 파일 맨 끝 푸터의 매직 값 0x5A6F12E1로 식별됩니다 — 또는 최신 UE5 타이틀에서는 IoStore .utoc/.ucas 컨테이너로 들어갑니다.

한 시간을 쓰기 전에 범위부터 확인하세요

.locres가 덮는 것은 UI, 메뉴, 시스템 메시지, 튜토리얼 텍스트, 아이템과 스킬 이름, 자막입니다 — 보통의 게임에서 눈에 보이는 텍스트의 대략 90% 정도라고 보면 됩니다. RuneTranslate가 읽고 쓰는 부분이 그것입니다.

덮지 못하는 것: DataTable에 컴파일되거나 쿠킹된 `.uasset` 패키지에 구워진 텍스트입니다. 일부 스튜디오는 — 특히 규모가 작거나 블루프린트 위주로 만든 프로젝트에서 — 대사를 현지화 시스템이 아니라 거기에 둡니다. 그 문자열들은 읽을 수 있는 디렉터리 색인 없이 쿠킹된 패키지 안에 해시로 주소가 매겨져 있고, 제대로 읽으려면 출시된 게임에 들어 있지 않은 .usmap 매핑 파일이 필요합니다. 게임이 스크립트를 거기에 두었다면 추출 결과로 메뉴와 버튼만 돌아오고 대사는 하나도 없을 것이며, RuneTranslate는 성공한 척하는 대신 그것을 명시적인 범위 밖 결과로 보고합니다.

일찍 알아 두면 좋은 것: 가장 빠른 확인 방법은 프로젝트 생성 단계를 돌려 무엇이 나왔는지 보는 것입니다. Continue, Options, Are you sure? 같아 보이는 짧은 문자열 몇백 개뿐이라면 UI만 현지화되어 있고 스크립트는 아닙니다. 완전한 문장을 포함해 수천 개가 나오면 상태가 좋은 것입니다.

AES 키, 그리고 그것이 벽이 아닌 이유

출시된 pak 중 상당수는 AES-256으로 암호화되어 있습니다 — 정확히는 IV 없는 ECB 모드이고, 아카이브의 색인에, 그리고 흔히 개별 항목에도 적용됩니다. 키가 없으면 아카이브는 불투명합니다: 안에 무엇이 들었는지 목록조차 볼 수 없습니다.

키를 되찾을 수 있는 이유는 단순합니다. 게임은 네트워크도 라이선스 서버도 없는 기계에서 런타임에 자기 아카이브를 읽어야 하므로, 키가 출시 바이너리 안에 평범한 데이터로 들어 있습니다. RuneTranslate는 실행 파일과 그 DLL을 훑어 32바이트 창을 모으고, 엔트로피 관문으로 걸러 내고(진짜 AES 키는 32바이트 중 서로 다른 바이트가 최소 25개입니다), 색인의 첫 블록을 복호화해 앞쪽 값이 그럴듯한 문자열 길이로 읽히는지 값싼 검사를 한 뒤, 살아남은 후보를 제대로 검증합니다: 색인 전체를 복호화해 그 SHA-1을 pak 자신의 푸터가 기록해 둔 해시와 비교합니다. 바로 그 마지막 단계가, 떠돌아다니는 엔트로피 순위식 키 탐색기들과 이것을 가르는 차이입니다 — 후보는 아카이브가 스스로 기록해 둔 해시를 재현하거나, 아니면 기각됩니다. 틀린 키가 받아들여지는 일은 있을 수 없습니다.

어떤 게임은 키를 원시 바이트가 아니라 텍스트로 저장하고, 어떤 게임은 바이너리 안 여러 명령어에 나눠 둡니다. 두 경우 모두 처리됩니다. 그래도 안 되면 새 프로젝트 대화상자가 16진수(0x… 또는 64자리 16진수)나 base64로 붙여 넣은 키를 받습니다. 한 번 복구된 키는 프로젝트별로 캐시되므로, 내보낼 때마다 85 MB짜리 실행 파일을 다시 훑지 않습니다.

UE5 IoStore는 다르고, 추출은 표적을 좁힙니다

UE5 타이틀은 평범한 pak 대신 IoStore 컨테이너를 배포하는 경우가 점점 늘고 있습니다: .utoc 디렉터리와 .ucas 데이터 블롭이 짝을 이루고, Oodle 압축과 자체 암호화를 씁니다. 여기서 순진한 접근은 전체를 언팩하는 것인데, 105 GB짜리 게임에서 그것은 접근법이라고 할 수도 없습니다.

RuneTranslate는 retoc(MIT 라이선스)를 번들해, 컨테이너를 현지화 파일만 걸러 낸 레거시 pak으로 변환하라고 지시합니다 — to-legacy -f locres --no-shaders --no-script-objects에 해당합니다. 105 GB짜리 IoStore 타이틀이 몇 킬로바이트의 .locres로 걸러지며, 몇 시간이 아니라 몇 초가 걸립니다. retoc은 컨테이너 자체의 AES와 Oodle도 처리하므로, 낱개 pak이 부딪힐 수 있는 Oodle 문제를 IoStore 게임은 비껴갑니다.

이 이야기의 중요한 절반은, IoStore가 복잡하게 만드는 것이 읽기뿐이라는 점입니다. 쓰기는 어느 쪽이든 똑같으며, 그것이 다음 절의 내용입니다.

결과물은 다시 빌드한 게임이 아니라 오버라이드 pak입니다

이 부분은 어느 경쟁 가이드도 제대로 설명하지 않는 대목이고, 일단 작동하기 시작하면 Unreal 번역이 값싸지는 이유이기도 합니다.

Unreal은 pak 파일을 정해진 순서로 마운트하며, 이름이 `_P`로 끝나는 아카이브는 맨 마지막에 마운트됩니다. 나중에 마운트된 쪽이 이깁니다. 그래서 여러분이 수정한 .locres만 담은 작은 아카이브를 기본 게임이 쓰는 것과 같은 가상 경로에 두면, 그것이 원본을 그냥 가려 버립니다 — 현지화 매니저는 여러분 것을 불러오고 배포된 원본은 아예 보지 않습니다.

  • 재서명이 필요 없습니다. pak 서명은 완전히 별개의 RSA 장치이고, 출시된 소비자용 타이틀에서 강제되는 일이 드뭅니다. 오버라이드는 그것을 건드리지 않습니다.
  • 출력에는 AES 키가 필요 없습니다. 오버라이드는 암호화도 압축도 없이 쓰입니다. 키는 애초에 원본을 읽기 위해서만 필요했습니다.
  • 게임을 다시 패킹하지 않습니다. 기본 아카이브는 손대지 않습니다. 60 GB 설치본은 그대로 60 GB이고, 여러분의 번역은 킬로바이트로 재는 파일 하나입니다.
  • IoStore 게임에서도 작동합니다. .locres는 Zen 패키지 로더가 아니라 pak 파일 시스템을 통해 읽히므로, 에셋이 전부 .utoc/.ucas에 있는 UE5 게임도 평범한 낱개 _P.pak을 집어 갑니다.

설치는 만들어진 _P.pak을 <Game>/Content/Paks/에 — 원본들이 놓인 바로 그 폴더에 — 복사하는 것입니다. 어떤 게임은 ~mods/ 하위 폴더도 마운트하는데 그쪽도 똑같이 잘 됩니다. 번역을 없애는 것은 그 파일 하나를 지우는 일이라, 되돌리기가 간단하고 일찍 시험해 보기에도 안전합니다.

단계

  1. 다운로드 페이지에서 RuneTranslate를 설치하고 로그인하세요. 첫 실행 시 무료 Patreon 로그인이 필요합니다. 무료 등급은 모든 엔진과 모든 제공자를 열어 주며, 처리량을 조절하고 프로젝트를 한 번에 하나만 보관합니다.
  2. 새 프로젝트를 만들고 게임의 루트 폴더 — 실행 파일과 <Game> 디렉터리가 있는 그 폴더 — 를 지정하세요. 감지는 Content/Paks와 pak 푸터 매직, 또는 .utoc/.ucas를 찾습니다.
  3. 아카이브가 암호화되어 있다면 키 복구가 돌게 두세요. 출시 바이너리를 훑어 각 후보를 pak 자신의 색인 해시와 대조해 검증합니다. 아무것도 나오지 않으면 대화상자에 키를 붙여 넣으세요.
  4. 추출이 끝나기를 기다리세요. 원본 컬처의 .locres 항목들이 현지화 대상별로 묶여, 검토할 준비가 된 채로 나옵니다.
  5. 제공자를 골라 번역하세요. 짧은 UI 문자열과 긴 대사를 서로 다른 제공자로 보낼 수 있으니, 돈이 값어치를 하는 곳에만 쓸 수 있습니다.
  6. 돌아온 결과를 검토하세요. 기계 번역이 가장 약한 곳이 메뉴 문자열입니다 — 맨 Save나 Load에는 문맥이 없고, 두 단어짜리 버튼이 문장으로 돌아오면 위젯을 넘칩니다.
  7. 내보내세요. RuneTranslate는 수정된 .locres를 올바른 엔진 상대 경로에 담은, 암호화되지 않은 _P.pak 하나를 씁니다.
  8. 그 파일을 <Game>/Content/Paks/에 복사하고 게임을 실행하세요.

게임 전체를 제공자에 돌리기 전에, 문자열 몇 개만 번역한 상태로 8단계까지 가서 시험해 보세요. 오버라이드가 무시될 상황이라면 — 잘못된 폴더, 잘못된 컬처, 특이한 마운트 구성 — 문자열 9,000개 값을 치른 뒤가 아니라 5분 안에 알아내는 편이 낫습니다.

플레이스홀더와 리치 텍스트

Unreal의 FText 서식은 위치 인자에 {0}, {1}을, 이름 인자에 {PlayerName}, {Count}를 쓰고, 인라인 스타일에는 </>로 닫는 <RichText> 마크업을 씁니다. 번역 제공자가 그중 하나를 떨어뜨리거나 망가뜨리면, 게임은 살짝 어색한 문장을 보여주는 것이 아니라 깨진 서식 문자열을 보여주거나 그 인자를 줄에서 조용히 지워 버립니다.

RuneTranslate는 제공자가 문자열을 보기 전에 그 하나하나를 중립적인 플레이스홀더로 가리고, 나중에 복원합니다. 제공자는 표식을 통과해서가 아니라 표식을 비껴서 번역하므로, 중괄호가 오타처럼 보인다고 판단한 모델이 인자를 지워 버릴 수 없습니다. 여기서 더 나아가 특정 문자열을 번역에서 아예 붙들어 두고 싶다면 정규식 제외 필터가 어느 엔진에서나 작동하고, 용어집은 고유명사를 게임 전체에서 일정하게 유지해 줍니다.

악센트 함정 — 폰트 문제가 아니라 인코딩 버그입니다

이것은 증상이 정확히 반대 방향을 가리키기 때문에 따로 기록해 둘 가치가 있습니다. Unreal은 문자열을 길이 접두사와 함께 직렬화합니다: 양수 길이는 한 글자당 1바이트를, 음수 길이는 UTF-16을 뜻합니다. 엔진은 모든 문자가 7비트 ASCII일 때만 좁은 형식을 고릅니다 — 검사가 0x7F를 넘는 것은 전부 거부합니다. 로더도 같은 방식으로 만들어져 있어서, 상위 바이트가 든 좁은 문자열을 건네받으면 그 하나하나를 그대로 ?로 바꿔 버립니다.

실질적인 결과는 이렇습니다: 좁은 형식으로 쓰인 poción mágica라는 번역이 플레이어에게는 poci?n m?gica로 도착합니다. 그리고 영향을 받는 구간은 U+0080–U+00FF인데, 정확히 스페인어, 프랑스어, 독일어, 포르투갈어, 이탈리아어와 북유럽 언어들의 악센트 글자입니다. 폴란드어, 터키어, 체코어, 그리스어, 키릴 문자, 한국어, 일본어, 중국어는 모두 U+00FF 위에 있어 자동으로 넓은 쪽 분기를 타므로 영향을 받지 않습니다.

그러니 지문은 이것입니다: 스페인어에서는 악센트가 깨지는데 러시아어는 멀쩡하다. 이 현상을 본다면, 게임 폰트에 글자가 없어서가 아니라 그 파일을 쓴 도구의 인코딩 버그입니다 — 글자가 없으면 네모 상자나 아무것도 아닌 것으로 그려지지, 물음표로 그려지지 않습니다. RuneTranslate에도 정확히 이 버그가 있었고 0.49.4에서 고쳤습니다. 이제 인코더는 한곳에만 있고, ASCII 밖의 것은 전부 넓은 형식으로 씁니다. 이 바닥의 다른 도구들이 여전히 이것을 틀리게 처리하고 있어서 알아 둘 가치가 있습니다.

제공자 고르기

아홉 개 제공자 중 셋은 API 키가 전혀 필요 없고 — Google, 무료 DeepL, 그리고 DeepL의 Classic / Next-gen 모델 — 무료 등급이 그 셋을 다 줍니다. 대부분이 UI인 게임이라면 무료 제공자로도 정말 충분합니다. 대사가 많은 타이틀에서는 LLM 제공자가 문맥을 훨씬 잘 다룹니다. OpenAI, Anthropic, DeepSeek, 모든 OpenAI 호환 엔드포인트, 그리고 Ollama나 LM Studio를 통한 로컬 모델을 모두 쓸 수 있습니다. 제공자 비교가 각각 무엇에 강하고 무엇에 약한지를 실제 비용 수치와 함께 짚어 줍니다.

문제 해결

게임은 실행되는데 아무것도 번역되어 있지 않습니다

거의 언제나 셋 중 하나입니다. 파일이 <Game>/Content/Paks/에 있지 않은 경우 — 실행 파일 옆에 두는 것은 아무 소용이 없습니다. 파일 이름이 _P 접미사를 잃은 경우 — 그러면 평범한 알파벳 순서로 마운트되어 기본 pak이 이길 수 있습니다. 아니면 게임이 여러분이 번역하지 않은 컬처로 돌고 있는 경우입니다: 시작할 때 결정된 컬처의 .locres를 불러오므로, en을 강제하는 게임은 ja용으로만 쓴 오버라이드를 무시합니다. 게임의 언어 설정부터 확인하세요.

Oodle로 압축된 낱개 pak에서 추출이 실패합니다

Oodle로 압축된 낱개 .pak에는 함께 번들할 수 없는 압축 해제기가 필요합니다. 게임이 IoStore 컨테이너도 함께 배포한다면 retoc 경로가 Oodle을 처리하므로 괜찮습니다. 낱개 pak뿐이라면 지금으로서는 여기서 막히며, 조용한 빈 결과가 아니라 명시적으로 보고됩니다.

게임 어디에도 .locres가 없습니다

그렇다면 텍스트가 쿠킹된 에셋에 컴파일되어 있고, 이 경로로는 거기에 닿지 않습니다. 가장 분명한 사례는 IoStore 색인이 파일 이름 없이 콘텐츠 해시로만 남겨진 대형 라이브 서비스 UE5 타이틀입니다 — 수십만 개의 청크에 .locres는 0개입니다. RuneTranslate는 컨테이너 전체를 갈아 대는 대신 그렇다고 말해 줍니다.

감지가 아예 걸리지 않습니다

Content/Paks 자체나 다른 게임들이 잔뜩 든 상위 폴더가 아니라, 실행 파일이 있는 폴더를 지정하세요. 그래도 감지되지 않는다면 패키징이 특이한 것이고 신고할 가치가 있습니다 — pak 형식은 버전마다 푸터 배치가 다르고, 아직 아무도 본 적 없는 방언이야말로 딱 추가되기 좋은 종류입니다.

정직한 한계

Unreal 지원은 최선의 노력입니다. 낱개 pak과 암호화된 pak 안, 그리고 UE5 IoStore 안의 .locres가 검증된 경로이며, UE4 타이틀에서 스페인어로 인게임 플레이 가능함이 확인되었습니다. DataTable과 쿠킹된 .uasset 텍스트는 다루지 않습니다. IoStore 대응물이 없는 Oodle 압축 낱개 pak은 지원되지 않습니다. 서명이 강제되는 pak은 오버라이드할 수 없지만, 실제로는 드뭅니다. 그리고 형식이 엔진 버전과 스튜디오마다 워낙 다르니, 첫 내보내기는 결과물이 아니라 시험으로 다루세요.

여러분이 손에 쥐게 되는 것은 자기 PC에 보관하는 플레이 가능한 번역 빌드 — 사실상 여러분 자신의 한글패치 — 입니다: 원본 게임은 손대지 않은 채로, 지우기만 하면 전부 되돌릴 수 있는 작은 파일 하나가 더해진 상태요. 엔진을 비교하거나 여러분의 게임이 다뤄지는지부터 확인하고 싶다면 Unreal 엔진 페이지에 기술적 세부가 있고, 전체 엔진이 Unity와 RPG Maker를 포함한 열일곱 개 형식을 나열합니다. 전 과정이 처음이라면 일반 안내로 시작한 뒤 Unreal 특유의 부분을 보러 여기로 돌아오세요.

관련 읽을거리
01

RPG Maker(쯔꾸르) 게임을 번역하는 방법

rpg-makerhow-toenginecontrol-codes2026년 8월 18일 · 10 분
읽기 →
02

게임의 .po 및 .mo 파일을 번역하는 방법 (gettext)

gettextpomoenginetutorial2026년 8월 4일 · 7 분
읽기 →
03

AliceSoft System 게임 번역하는 방법 (Rance, Evenicle…)

alicesoftranceengine2026년 6월 26일 · 6 분
읽기 →

RuneTranslate를 써볼 준비가 되셨나요?

무료 등급에서 모든 엔진과 모든 번역 제공자가 열립니다. Supporter($3/mo)로 최고 속도가 열립니다.

Windows용 다운로드