> For the complete documentation index, see [llms.txt](https://docs.overdare.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.overdare.com/korean/manual/studio-manual/game-development/localization.md).

# Localization

## 개요

Localization(현지화)은 다양한 언어를 사용하는 플레이어에게 동일한 경험을 제공하기 위한 기능입니다.

**월드 이름, 설명**과 같은 아웃게임 텍스트부터 월드 내 UI, 상호작용 메시지, 시스템 문구 등 **인게임 텍스트**까지 번역하여 표시할 수 있습니다.

이 기능을 활용하면 다양한 국가의 플레이어에게 자연스러운 경험을 제공할 수 있으며, 월드 접근성을 높여 **사용자 유입 확대**와 **수익 극대화**에 도움을 줄 수 있습니다.

## 특징

이 시스템은 다음과 같은 특징을 가집니다:

* UI, ProximityPrompt에 표시되는 텍스트를 자동으로 수집하여 크리에이터 허브에 등록
* 번역 데이터는 크리에이터 허브에서 통합 관리
* 등록된 번역 데이터를 기반으로 플레이어의 언어 설정에 따라 자동으로 번역 적용
* 스크립트를 통해 동적 텍스트도 번역 가능

## 지원 언어

현재 OVERDARE는 **영어, 힌디어, 포르투갈어(브라질)**&#xB97C; 지원합니다.

유사한 언어는 지원 언어로 자동 매칭됩니다. 예를 들어 영국 영어는 영어로, 유럽 포르투갈어는 브라질 포르투갈어로 매칭됩니다.

지원되지 않는 언어는 원문으로 표시될 수 있습니다.

| 언어         | 언어 코드   | 유사 언어 계열 예시        |
| ---------- | ------- | ------------------ |
| 영어         | `en`    | `en-us`, `en-gb` 등 |
| 힌디어        | `hi`    | `hi-in` 등          |
| 포르투갈어(브라질) | `pt-br` | `pt`, `pt-pt` 등    |

각 언어에 대한 번역 텍스트가 입력되지 않은 경우, 해당 항목은 기본 언어(원문)로 표시될 수 있습니다. 월드 활성화 및 사용자 경험에 영향을 줄 수 있으므로, **지원하는 모든 언어에 대해 번역 텍스트 입력을 권장합니다.**

## 사용 방법

1. Localization 기능은 월드를 **퍼블리시한 이후에 사용**할 수 있습니다.\
   (월드가 퍼블리시되지 않은 경우, 먼저 퍼블리시를 진행해야 합니다.)

   <figure><img src="/files/h2GquEsJeerpchGepWUM" alt=""><figcaption></figcaption></figure>
2. 스튜디오의 **Game Settings**의 **Localization 탭**에서 **자동 텍스트 수집(ATC)**&#xACFC; **번역 콘텐츠 사용**을 활성화합니다.\
   (Edit in Hub 버튼을 누르면 크리에이터 허브의 Localization 관리 페이지로 이동할 수 있습니다.)

   <figure><img src="/files/iAAAf0RLi8vQdlfj4D7F" alt=""><figcaption></figcaption></figure>
3. **플레이 테스트**를 실행합니다.
4. 테스트 중 UI 및 ProximityPrompt에 텍스트가 표시되면 해당 텍스트가 **수집 대상으로 자동 등록**됩니다.\
   (수집 과정은 내부적으로 처리되며, 한 번의 플레이 테스트에서 수집 가능한 텍스트 수에는 제한이 있습니다. 이 제한을 초과하면 추가 텍스트는 수집되지 않고 경고 로그가 출력됩니다.)
5. **플레이 테스트 종료 시**, 수집된 텍스트가 크리에이터 허브의 번역 테이블에 **자동으로 등록**되며, 지원하는 모든 언어에 대해 번역 항목이 함께 생성됩니다.

   <figure><img src="/files/2PYgB8zEdHlSkXeUti9w" alt=""><figcaption></figcaption></figure>
6. 등록된 텍스트는 크리에이터 허브에서 확인할 수 있으며, **각 언어별로 번역 텍스트를 입력**하고 관리할 수 있습니다.\
   (입력 후 **Save 버튼**을 눌러 저장해야 합니다.)

   <figure><img src="/files/50kM5JeEEq5rvYmiKnFl" alt=""><figcaption></figcaption></figure>
7. ATC로 수집이 어려운 저빈도 텍스트나 조건부 텍스트는 크리에이터 허브의 **Table Management 탭**에서 CSV를 통해 수동으로 등록할 수 있습니다.

   <figure><img src="/files/Rtx9iS3GZyZP2bewArqJ" alt=""><figcaption></figcaption></figure>
8. 월드 이름, 설명과 같은 월드 정보 데이터는 기본적으로 구성되어 있습니다.

   <figure><img src="/files/7Y2nBoV4gKzOO5IetecN" alt=""><figcaption></figcaption></figure>

## 번역 테스트

**Localization Preview**에서 언어를 선택하여 번역 결과를 확인할 수 있으며, 플레이 중에도 언어를 변경할 수 있습니다.

<figure><img src="/files/5klibLff78N9Bs0HPe1k" alt=""><figcaption></figcaption></figure>

## 상세

### 자동 텍스트 수집 (ATC)

스튜디오 환경에서 플레이 테스트 중 UI 또는 ProximityPrompt에 텍스트가 표시될 때 해당 텍스트는 자동으로 수집되며, 수집된 텍스트는 **플레이 종료 시** 크리에이터 허브의 번역 테이블에 등록됩니다.

#### **수집 대상**

* TextLabel, TextButton의 텍스트 속성 (Text)
* ProximityPrompt의 상호작용 텍스트 속성 (ActionText, ObjectText)

#### **수집 조건**

다음 조건을 만족하는 경우에만 텍스트가 수집됩니다.

* **자동 텍스트 수집(ATC)이 활성화**된 상태
* **스튜디오 환경의 플레이 테스트 상태** (모바일 환경에서는 수집되지 않습니다.)
* UI 또는 ProximityPrompt의 **AutoLocalize 속성이 활성화**된 경우
  * UI의 경우, 조상과 자식 UI 모두에서 AutoLocalize가 활성화된 경우에만 텍스트가 수집됩니다.

#### 동작 방식

* 화면에 표시되는 텍스트는 플레이 중 **실시간으로 수집**됩니다.
  * 허브의 Location 필드에는 텍스트가 수집된 경로가 StarterGui.ScreenGui.TextButton와 같은 형식으로 기록됩니다.
* 스크립트를 통해 **동적으로 할당된 텍스트**도 수집 대상에 포함됩니다.
* 이미 허브에 등록된 텍스트는 중복 등록되지 않습니다.
* 수집된 텍스트는 **플레이 종료**시 허브로 전송됩니다.

#### **수집 제한**

* 한 번의 플레이 테스트에서 수집 가능한 텍스트 수에는 제한이 있습니다.
* 제한을 초과하면 이후 텍스트는 수집되지 않으며, **경고 로그**가 출력됩니다.
* 루프 문에서 텍스트를 반복적으로 할당하는 등 과도한 텍스트 생성이 발생하는 경우, 구조를 점검한 후 플레이 테스트를 다시 실행해야 합니다.
* **수집이 불필요한 텍스트는 AutoLocalize 속성을 반드시 비활성화하세요.**

### 번역 텍스트 적용

플레이 테스트 중 UI 또는 ProximityPrompt에 텍스트가 표시될 때, 해당 텍스트가 크리에이터 허브에 등록되어 있고 번역된 텍스트가 존재하는 경우 자동으로 번역이 적용됩니다.

#### 번역 적용 **대상**

* TextLabel, TextButton의 텍스트
* ProximityPrompt의 상호작용 텍스트

#### 적용 조건

* **번역 콘텐츠 사용이 활성화**된 상태
* **스튜디오 환경의 플레이 테스트 상태 또는 모바일 환경에서 월드에 접속한 상태**
* UI 또는 ProximityPrompt의 **AutoLocalize 옵션이 활성화**된 경우
  * UI의 경우, 부모와 자식 UI 모두에서 AutoLocalize가 활성화된 경우에만 텍스트가 번역됩니다.

#### 수정 사항 반영 시점

* 번역 데이터의 변경 사항은 플레이 테스트 **재실행** 또는 월드 **재접속시 반영**됩니다.
* 모바일 환경에서는 변경 사항이 즉시 반영되지 않으며, **약 5분 정도 후**에 적용될 수 있습니다.

#### Context 기반 번역 적용 규칙

번역은 **Context 값**과 UI 또는 ProximityPrompt의 **위치**를 기준으로 다음과 같이 적용됩니다.\
(이 규칙은 Translate 메서드를 사용하는 경우에도 동일하게 적용됩니다.)

예를 들어 허브에 다음과 같이 등록되어 있을 때,

<table><thead><tr><th width="107.666748046875">원문(Source)</th><th width="117.3333740234375">번역 텍스트</th><th width="387.9998779296875">Context</th><th>비고</th></tr></thead><tbody><tr><td>강화</td><td>강화</td><td></td><td>기본 번역</td></tr><tr><td>강화</td><td>아이템 강화</td><td>PlayerGui.ScreenGui.ItemPopup.EnhanceButton</td><td>UI용 번역</td></tr><tr><td>강화</td><td>강화 몬스터</td><td>ServerStorage.Monster.NameTag.GradeLabel</td><td>몬스터용 번역</td></tr></tbody></table>

* Context가 **일치**하면 해당 번역이 적용됩니다.
  * UI 또는 ProximityPrompt의 경로가 PlayerGui.ScreenGui.ItemPopup.EnhanceButton이면,\
    -> **아이템 강화**가 적용됩니다.
* Context가 **일치하지 않으면** Source만 있는 번역(기본 번역)이 적용됩니다.
  * UI 또는 ProximityPrompt의 경로가 위 Context들과 모두 다르면,\
    -> 기본 번역인 **강화**가 적용됩니다.
* **기본 번역이 없으면** Context가 있는 번역이 적용될 수 있습니다.
  * 예를 들어 강화에 대한 기본 번역이 없고 Context 번역만 존재한다면,\
    -> **아이템 강화** 또는 **강화 몬스터**와 같이 Context 번역이 적용될 수 있습니다.

## 번역 데이터 관리

### Localization 페이지

스튜디오의 Game Settings의 Localization 탭에서 **Edit in Hub 버튼**을 누르면 크리에이터 허브의 Localization 관리 페이지로 이동할 수 있습니다.

<figure><img src="/files/NdPd4sFDFUzoaz48uiPL" alt=""><figcaption></figcaption></figure>

또는 크리에이터 허브의 Dashboard에서 월드를 선택한 뒤, **Localization 탭**으로도 접근할 수 있습니다.

<figure><img src="/files/M2xMi8vH8qsSOkGd5jf6" alt=""><figcaption></figcaption></figure>

### 번역 텍스트 관리

**Languages 탭**에서 언어를 클릭하면 해당 언어의 **월드 정보**와 **인게임 텍스트**의 번역을 관리할 수 있는 페이지로 이동합니다.

또는 **Translation Workspace 탭**으로도 이동할 수 있습니다.

<figure><img src="/files/eBWa3zLjGxHFxZ6tgHbs" alt=""><figcaption></figcaption></figure>

#### 월드 정보 관리

**Information 탭**에서 지원 언어별로 **월드 이름**(Name)과 **설명**(Description)의 번역 텍스트를 입력할 수 있으며, 수정 내역은 Translation History에 기록됩니다.

<figure><img src="/files/eohiOTk37eTO99zg2pKk" alt=""><figcaption></figcaption></figure>

#### 인게임 텍스트 관리

**Strings 탭**에서 지원 언어별로 인게임에서 사용되는 데이터의 번역 텍스트를 입력할 수 있으며, 수정 내역은 Translation History에 기록됩니다.

각 항목을 선택하면 등록된 데이터의 번역 내용을 수정하거나 삭제할 수 있습니다.

<figure><img src="/files/iZ8Opgp6yr5tU8HWciFU" alt=""><figcaption></figcaption></figure>

기본적으로 플레이 테스트 중 ATC를 통해 수집된 텍스트는 자동으로 등록되며, **Add Entry 버튼**을 통해 수동으로도 추가할 수 있습니다.

<figure><img src="/files/mNBjpCfGCyPBplUMSAQg" alt=""><figcaption></figcaption></figure>

수동 추가시 입력 필드는 다음과 같이 구성되며, 내용을 입력한 후 **Add 버튼**을 클릭하면 번역 항목이 등록됩니다.

동일한 원문을 가진 텍스트는 Context가 다를 때에만 중복 등록이 가능합니다.

<table><thead><tr><th width="167">이름</th><th width="364.6666259765625">설명</th><th>예시</th></tr></thead><tbody><tr><td>Text to translate</td><td>번역의 기준이 되는 원문 텍스트</td><td>Level</td></tr><tr><td>Key</td><td>번역 항목을 식별하기 위한 고유 값 (선택 입력)</td><td>UI_Text_Level</td></tr><tr><td>Context</td><td>텍스트가 사용되는 UI 위치 (선택 입력)</td><td>PlayerGui.PlayerHUD.TopFrame.Lv</td></tr><tr><td>Example</td><td>번역 참고를 위한 설명 (선택 입력)</td><td>플레이어 레벨 표시용 텍스트</td></tr></tbody></table>

### 설정 관리

**Settings 탭**에서 자동 텍스트 수집 및 번역 텍스트 적용 옵션의 활성화 여부를 설정할 수 있습니다.

설정한 옵션은 스튜디오와 연동되며, 스튜디오에서 변경한 설정도 허브에 동일하게 반영됩니다.

<figure><img src="/files/olgRaa9oP45afL4QcK8n" alt=""><figcaption></figcaption></figure>

### Table Management

**Table Management 탭**에서는 번역 데이터를 CSV로 다운로드하거나, CSV 업로드를 통해 수정할 수 있습니다.

저빈도 UI나 조건부 UI의 경우 ATC만으로는 수집이 어려울 수 있습니다. 이러한 경우 ATC에 의존하기보다는 필요한 데이터를 CSV에 미리 정의한 뒤 업로드하여 관리하는 것을 권장합니다.

<figure><img src="/files/muoFx9YqK3zu3w76TU5V" alt=""><figcaption></figcaption></figure>

* **Upload CSV**: CSV 파일을 업로드하여 인게임 텍스트와 번역 데이터를 추가, 수정할 수 있습니다. 기존 데이터를 기반으로 변경 사항만 반영됩니다.
* **Download CSV**: 현재 번역 테이블을 CSV 파일로 다운로드할 수 있습니다. 다운로드한 파일을 통해 번역 상태를 확인하거나, 수정 후 다시 업로드하여 사용할 수 있습니다.
* **Delete Table**: 번역 테이블에 등록된 모든 인게임 데이터를 삭제합니다. 이 작업은 되돌릴 수 없으므로 신중하게 사용하시기 바랍니다.

## 스크립트 기능

### 로케일 정보 확인

LocalizationService를 통해 플레이어 및 시스템의 언어 정보를 확인할 수 있습니다.

이를 활용하면 플레이어의 언어 설정이나 지역에 따라 다른 처리를 할 수 있습니다.

```lua
local LocalizationService = game:GetService("LocalizationService")

local PlayerLocaleId = Player.LocaleId -- 플레이어 계정에 설정된 언어
local ClientLocaleId = LocalizationService.ClientLocaleId -- 현재 클라이언트에서 사용 중인 언어
local SystemLocaleId = LocalizationService.SystemLocaleId -- 플레이어가 사용하는 기기의 OS 언어
local CountryRegion = LocalizationService:GetCountryRegionForPlayerAsync(Player) -- 플레이어의 접속 지역(국가 코드)
```

ClientLocaleId와 SystemLocaleId는 실행 환경의 로케일 값을 반환합니다. 클라이언트에서는 플레이어 기준으로 동작하지만 서버에서 사용할 경우 서버 기준 값이 반환됩니다.

따라서 플레이어별 로케일 처리가 필요한 경우 서버에서 사용하는 것은 권장하지 않습니다.

### Translator 가져오기

Translator는 특정 언어를 기준으로 번역을 수행하는 객체로, 번역 텍스트를 가져올 때 사용됩니다.

```lua
-- 플레이어의 언어 설정을 기준으로 Translator를 가져옵니다.
local Translator1 = LocalizationService:GetTranslatorForPlayerAsync(Player)
print(Translator1.LocaleId)

-- 특정 언어 코드를 기준으로 Translator를 가져옵니다.
local Translator2 = LocalizationService:GetTranslatorForLocaleAsync("en")
print(Translator2.LocaleId)
```

### 스크립트로 번역 처리

아이템 이름이나 레벨 등 변수 값에 따라 문장이 달라지거나, 동일한 텍스트라도 상황에 따라 다른 번역이 필요한 경우 스크립트를 통해 번역을 처리할 수 있습니다.

#### Key 기반 번역(FormatByKey)

FormatByKey는 Key를 기준으로 번역 텍스트를 가져오며, 문장 내에 치환이 필요한 값(아이템 이름, 레벨 등)은 Args를 통해 전달합니다.

아이템 이름, 레벨, 수량처럼 상황에 따라 문장이 달라지는 텍스트를 처리할 때 사용하기 적합합니다.

```lua
local Translator = LocalizationService:GetTranslatorForPlayerAsync(Player)

local Key = "ITEM_LEVEL_UP" -- 번역 데이터를 조회하기 위한 Key
local Args = { ItemName = "Sword", PrevLv = 1, NextLv = 2 } -- 문장에서 치환될 값
local TranslatedText = Translator:FormatByKey(Key, Args)

SomeUI.Text = TranslatedText
```

Args로 전달하는 각 값의 이름은 허브에 등록된 번역 데이터 내에서 사용하는 이름과 반드시 동일해야 하며, 필요한 항목의 개수 또한 일치해야 합니다.

<figure><img src="/files/uzhJttOINfQHPCz9xgJ4" alt=""><figcaption></figcaption></figure>

Args에 전달할 수 있는 데이터 타입은 다음과 같습니다.

* number
* string
* bool
* instance (name)
* CFrame
* Vector3
* Vector2
* Color3
* BrickColor
* MenuItem

#### Context 기반 번역(Translate)

```lua
local Translator = LocalizationService:GetTranslatorForPlayerAsync(Player)

local Context = PlayerGui.ScreenGui.ItemPopup.EnhanceButton -- 텍스트가 사용되는 경로 (Context)
local Source = "강화" -- 번역의 기준이 되는 원문 텍스트
local TranslatedText = Translator:Translate(Context, Source)

SomeUI.Text = TranslatedText
```

기본적으로 번역의 기준이 되는 텍스트는 중복될 수 없지만, Context가 다른 경우에는 각각 별도의 번역 데이터로 등록할 수 있습니다.

이를 통해 “강화”는 아이템 강화(Enhance), 스킬 강화(Upgrade), 강화된 적(Enchanted)처럼 상황에 따라 다르게 번역될 수 있으며, Context를 통해 이를 구분할 수 있습니다.

<figure><img src="/files/AN9AWC6kS4NNLfC1ToTr" alt=""><figcaption></figcaption></figure>

### LocalizedText로 원문 가져오기

LocalizedText는 현재 언어 기준으로 번역된 텍스트를 반환하는 속성입니다.

UI에 실제로 표시되는 번역 결과를 확인할 때 사용할 수 있습니다.\
(ProximityPrompt에서는 제공되지 않습니다.)

```lua
print(SomeUI.LocalizedText .. "(원문 : " .. SomeUI.Text .. ")")
```

## 활용 예시

* 월드 이름과 설명을 다양한 언어로 제공하면, 글로벌 사용자에게 월드를 효과적으로 노출하고 유입을 확대할 수 있습니다.
* UI, 버튼, 안내 메시지 등을 플레이어의 언어에 맞게 제공하면, 게임 이해도를 높이고 이탈률을 줄일 수 있습니다..
* 다국어 환경에서 문장 구조가 다른 경우에도, FormatByKey를 사용하면 각 언어에 맞는 자연스러운 문장을 구성할 수 있습니다.
* 동일한 텍스트라도 상황에 맞는 번역(Context)을 적용하면 보다 자연스러운 표현을 제공할 수 있어 사용자 경험을 개선할 수 있습니다.
