LOCALIZATION

All displayed strings in a package can be set to use a one or more localization (*.loc) files. These files contain entries of formatted data that represent "variables" to identify the strings required, which are then paired with all possible return strings based on the currently selected (and available) languages. For Missions and SimObjects, these *.loc files should be placed in a folder called "localization" at the top level of the package. For example with an aircraft package, the localization folder would be in the PackageSources/SimObject/Airplanes/<aircraft> directory, beside the aircraft.cfg and the texture folders, model folders, etc...

Example Showing The Localization Folder For An Aircraft

 

Apart from the folder location, the files themselves can be called whatever you require, as long as they have the *.loc extension, and they can be placed in sub-folders if needed. You can also have one, two, three or however many files you want, as they will all be parsed when the package is loaded.

 

For any other asset type that is not a Mission or SimObject, the localizations folder should go at the top level of the package, and should be created using the project editor, as shown here: Localization.

 

 

*.loc File Format

The *.loc file is essentially just a file of JSON that contains various object literals that define the variables used for localized text along with the text itself. The basic structure of this JSON is as follows:

{
  "LocalisationFile": {
    "Version": 2,
    "UUID": "00000000-0000-0000-0000-000000000000",
    "Languages": [
      "en-US",
      "fr-FR",
      "es-ES",
      "de-DE",
      "it-IT",
      "pl-PL",
      "pt-BR",
      "ru-RU",
      "ja-JP",
      "nl-NL",
      "nb-NO",
      "sv-SE",
      "fi-FI"
    ],
    "Strings": {
      "PARAMETER.1": {
        "UUID": "00000000-0000-0000-0000-000000000000",
        "LastModifiedBy": "someone",
        "LastModifiedDate": "2021-04-30 16:44:54",
        "LocalizationStatus": "TranslationNeeded",
        "Languages": {
          "en-US": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationOk"
          },
          "fr-FR": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "es-ES": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "de-DE": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "it-IT": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "pl-PL": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "pt-BR": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "ru-RU": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "ja-JP": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "nl-NL": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "nb-NO": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "sv-SE": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          },
          "fi-FI": {
            "Text": "foo-bar",
            "LocalizationStatus": "TranslationNeeded"
          }
        }
      },
      "PARAMETER.2": {
        "UUID": "00000000-0000-0000-0000-000000000000",
        "LastModifiedBy": "someone",
        "LastModifiedDate": "2021-04-30 16:44:54",
        "LocalizationStatus": "TranslationNeeded",
      },
      <!-- FURTHER JSON OBJECT LITERALS HERE -->
    }
  }
}

You can see from the above example that there are two "parameters" defined PARAMETER.1 and PARAMETER.2. It is important to note that each localization parameter entry must be unique to the package. So when you are creating your add-on files, you need to ensure that you only ever create unique parameters.

 

 

Creating The *.loc File(s)

As you can see from the code in the section above, the *.loc file format isn't that complicated and it's possible to create your own files by hand and manually input the data in them. However, we strongly recommend that instead you use MSFS Localization Manager to create your files. Not only will it ensure that your *.loc files are correctly formatted, it streamlines and makes easier the addition of translations and text, without the need for all the work required to create and maintain the files by hand. This program comes bundled with the SDK and will be installed in the Tools folder.

 

You can find a tutorial on how to use the MSFS Localization Manager here:

 

 

Using Localized Strings In Your Files

Actually adding localized strings to your add-on so that they are used automatically when a user installs the package is very simple and involves simply prefixing the localizable variable with "TT:". For CFG files, the format for this would be:

<parameter> = "TT:<VARIABLE_NAME>"

For example, say you want to localise the information that is stored in the aircraft.cfg file. In that file there are some specific parameters that are used to give information about the aircraft, and these can all be localized:

description = "TT:AIRCRAFT.DESCRIPTION"
ui_manufacturer = "TT:AIRCRAFT.UI_MANUFACTURER"
ui_type = "TT:AIRCRAFT.UI_MODEL"
ui_variation = "TT:AIRCRAFT.LIVERY.DEFAULT"

As you can see, you simply supply a variable and prefix it with TT:, and then Microsoft Flight Simulator will automatically do a string substitution based on the user's localization settings. This is also the same when you want to use localization in an XML file within any element. For example here is the <Airport> element that uses localized strings for various attributes:

<Airport country="TT:AIRPORT.MYNN.country" city="TT:AIRPORT.MYNN.city" name="TT:AIRPORT.MYNN.name" ident="MYNN" lat="25.03315828248019" lon="-77.45777558198010" alt="3.95300109890510" magvar="6.000000" trafficScalar="1.000000" airportTestRadius="2000.00000000000000">

Localised strings may also be used within an element rather than as an attribute, for example here we have some XML from a Model Definition file:

<UseTemplate Name="ASOBO_ELECTRICAL_Switch_Battery_Master_Template">
    <ID>2</ID>
    <NODE_ID>ELECTRICAL_Switch_Battery_STBY</NODE_ID>
    <ANIM_NAME>ELECTRICAL_Switch_Battery_STBY</ANIM_NAME>
    <ANIMTIP_0>TT:COCKPIT.TOOLTIPS.BATTERY_STBY_ARM</ANIMTIP_0>
    <ANIMTIP_1>TT:COCKPIT.TOOLTIPS.BATTERY_STBY_OFF</ANIMTIP_1>
    <TT_ICON>PUSH</TT_ICON>
</UseTemplate>

It's worth noting that you can use a single parameter in multiple places if you need to use the same localized text. For example, the name of the aircraft you are creating may be shown in various places, and so you can use a single localized parameter in multiple places to save on duplicating parameters and text.