Understanding Localization

# Course Introduction

A localization process is a must if a creator wishes to ensure their world is enjoyed by users of multiple regions. `LocalizationService` helps to provide text or resources that match the user's app language settings. In this lesson, we will explore the concept of translation and how to use `LocalizationService`.

##### Reference Guide

[Localizing to Format](docs/?postId=968) [Automatic Translation](\(docs/?postId=1072\)) [LocalDataSet](docs?postId=1120)

##### API Reference

[LocalizationService](/apiReference/Services/LocalizationService)

# What is localization?

In the simplest sense, localization is basically translating a word or phrase that the user sees in the worlds. For example, a World may have been created in Korean, but when users who have set their client language to English enter that World, a word like 사과 will be automatically translated as apple. However, the difference between translating and localizing is supporting not only the basic meaning of the language, but also the cultural context and tone of the world's many elements.

Localization is the process of translating the language and various elements of a world appropriate to the desired language and culture. An example would be how different regions list their dates. In Korea, the order is Year/Month/Day, (01/31/2023). In America and Canada, the order is normally Month/Day/Year (01/31/2023). In others, the order can be Day/Month/Year (31/01/2023). The way numbers are written also differs in different regions. For example, people write the number 1234567.89 as 1,234,567.89 in South Korea, the United States, and Canada. They use a comma (,) as the thousands separator and a period (.) as the decimal point. However, in France, Germany, and Austria, they write it as 1.234.567,89. They use a period (.) as the thousands separator and a comma (,) as the decimal point. Some regions even use spaces instead of thousands separators, such as 1 234 567.89.

Therefore, considering the expectations of users from different cultures and regions, it is necessary to express dates or numbers in formats that correspond to those regions. As such, localization is not just a simple translation, but the entire process of adjusting content so that users connecting from each cultural area can use content without confusion or inconvenience.

## Localization of MapleStory Worlds

MapleStory Worlds is aiming for a long-term global one build. As such, it is possible for clients from different regions to be connected together on a single server. So MapleStory Worlds supports simultaneous translation into multiple languages from a single text. [png](167479872265151ac9e8a10ee49638f070ced7e26e7b1)

However, the server should send the Localizing Key instead of directly sending the localized message itself. It communicates with the localizing key and outputs different data for each client language setting. Let's take a look at how to do actual localization in MapleStory Worlds with an example.

# Translate Text

You need to create a translation table to translate text according to the client language setting.

#### Create LocaleDataSet

Let's use LocaleDataSet to translate text in a simple way.

  1. Add a text entity in the UI editor. [png](1686728912583c7cafe2f6fa244b49e51195f776c6ed2) Modify the property in TextComponent for the new text entity as follows.

[{"Component":"TextComponent","Property":"FontSize","Value":"50.0"},{"Component":"TextComponent","Property":"Text","Value":"UI_Hello"},{"Component":"TextComponent","Property":"IsLocalizationKey","Value":"True"}]

  2. Create LocaleDataSet and enter the following.

[{"index":"ID","0":"1"},{"index":"Key","0":"UI_Hello"},{"index":"Source","0":"Hello!"},{"index":"ko","0":"안녕하세요!"},{"index":"en","0":"Hello!"}]

  3. Press the  [Start] button and run a test with the client's language set to Korean. You can see that 안녕하세요! is displayed. [png](1674808092988390b7fa2c4e648b28503ad01d9a744a5)

  4. Change File - Setting - Others - General - Language to (English) in the navigation menu. [png](1727238891918e6796e5e12344992b411122ba49c8ebf)

  5. Press the  [Start] button and run a test. Hello! is displayed.



    
    
    [png](167480819908819eb8fb051a2483d878600f5f3fa548f)
    

## GetText Function

You can easily set the TextComponent text to be translated with IsLocalizationKey, but use the `GetText()` function when you need to translate other texts or control translation in a script. The `GetText()` function finds a row in the Key column of the translation table with the same value as the key received as argument and returns the text value from the same column as the client language code in that row.

Let's look at how to display text for each language setting of the client with a simple example. Let's place 2 NPCs on the map and display appropriate names according to the language settings.

  1. Place 2 NPCs on the map. In this example, we have placed the two NPCs below. [png](167410631018585e61a9abb2544af96dbb18c261313f3)

     * npc-931
     * npc-845
  2. Modify the name of each NPC entity as shown below.

[{"NPC":"[png](1674097464492fb3054921620425a80664d1380f3f695)","Entity Name":"Stan"},{"NPC":"[png](16740974755475f8d0c294b5a491f907eefb8acc7bad1)","Entity Name":"Rina"}]

  3. Create LocaleDataSet and enter as follows.

[{"ID":"1","Key":"UI_TEXT_NPC_Stan","Source":"Stan","ko":"스탄","en":"Stan"},{"ID":"2","Key":"UI_TEXT_NPC_Rina","Source":"Rina","ko":"리나","en":"Rina"}]

  4. In the context menu of Workspace - MyDesk, click Create Scripts - Create Logic to add a new logic with the name LocalizationTest.

  5. Add properties to LocalizationTest as follows.
         
         @Component
         script CharacterReferences extends Component
         property Entity Stan = "/maps/map01/Stan"
         property Entity Rina = "/maps/map01/Rina"
         end
         



    
    
        
    6. Add the `OnBeginPlay()` function and enter the following. Set the execution space to **client only**.
        ```lua
    @Component
    script LocalizedNPCNameInitializer extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        self.Stan.NameTagComponent.Name = _LocalizationService:GetText("UI_TEXT_NPC_Stan")
        self.Rina.NameTagComponent.Name = _LocalizationService:GetText("UI_TEXT_NPC_Rina")
        end
    end
    

  7. Press the  [Start] button and run a test with the client's language set to Korean. You can see that the NPC names appear as below. [png](16741065097102ce4bfb23e3c453aaae7dc1b04f14365)   
If you change the language settings to English, you can see that the NPC names appear in English as shown below. [png](1674106659362b89a441ef8b045ed811972bb1bdd84e7)



### Translator

The LocalTranslator property is in LocalizationService.

  * The type of the LocalTranslator property is [Translator](/apiReference/Misc/Translator).
  * LocalTranslator includes LocaleId (string type property).



The next two lines of code return the same value.
    
    
    @Component
    script LocalizedTextGetter extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
            _LocalizationService:GetText("UI_TEXT_NPC_Stan")                   -- Stan
            _LocalizationService.LocalTranslator:GetText("UI_TEXT_NPC_Stan")     -- Stan
        end
    end
    

LocaleId of LocalTranslator is the language code for the currently executing client. For example, if the language for the currently executing client is Korean, the LocaleId of LocalTranslator is ko. If you call a function such as `GetText()` directly without using Translator created separately in LocalizationService, the function is performed based on the LocaleId for LocalTranslator. If the current client language setting is Korean and you want to import an English translation, you can write the code as follows.
    
    
    @Component
    script LocalizedTextLoader extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
            local enTranslator = _LocalizationService:GetTranslatorForLocale("en")
            enTranslator:GetText("UI_TEXT_NPC_Stan") -- Stan
        end
    end
    

# Resource Localization

The resources as well as the text can be localized as needed.

Let's go through an example.

  1. Press the [  ] image button to create an empty image and change its name to SpriteTest in the UI editor.

  2. Generate a new script component, SpriteLocalization. Then, add the component to the SpriteTest image created above.

  3. Open the SpriteLocalization script and add the property as follows.
         
         @Component
         script ResourceReference extends Component
         property string ResourceKey = ""
         end
         



    
    
      
    4. Add the `OnInitialize()` function and write its content as follows. Set the execution space to **client only**.
    
        ```lua
    @Component
    script SpriteLocalizer extends Component
        @ExecSpace("ClientOnly")
        method void OnInitialize()
        self.Entity.SpriteGUIRendererComponent.ImageRUID = _LocalizationService:GetText(self.ResourceKey)
        end
    end
    
    
    
    

  5. In the SpriteTest property editor, enter RESOURCE_LOGO to SpriteLocalization - ResourceKey.

[png](1674184215431d6a44d479721419f9e694e289de686ce)

  6. Open LocaleDataSet and add the following content.

     * Key : RESOURCE_LOGO
     * Source : 3110502e753742d39794e042c2657ce5
     * ko : 7ae6a288ee884b75a44851c59b595789
     * en : 3110502e753742d39794e042c2657ce5   

  7. Press the  [Start] button and run a test. The Korean logo appears when the language setting is Korean, and the English logo appears when the language setting is English.

[png](16741847984983e92b71d5e1f48d3b3469a98d7feb597)