Dynamic Client Localization System [DCLS]

Dynamic Client Localization System

Welcome to the Dynamic Client Localization System, DCLS.

Inspired by Arma 3’s localization system and seeing an accessibility issue with how many FiveM resources handle localization, I created DCLS. A simple and easy-to-edit system that solves a common problem within localization in the FiveM resource ecosystem, which I like to call the “global language problem”.
“Global Language Problem - When a software provides localization but forces all users to use the same language, regardless of a user’s choice or preference.”

Many community resources include localization systems, but these resources all have a common flaw, the servers decide what language gets displayed, not the players. DCLS solves this issue by putting the player in charge of their localization, using the already provided language option in GTA V.

With DCLS, your resources and systems will be accessible to players worldwide in the 13 different languages supported in GTA V, including English, French, German, Italian, Spanish, Korean, Japanese, Chinese, Russian, Polish, Portuguese, and Brazilian Portuguese. All done while respecting the language choice of all players through the in-game language option.
Only the languages available in GTA V are supported

Links

GitHub Repository
Documentation
Direct Download (Latest Version)

Why use DCLS

The main problem solved is accessibility, as every player is different.
Some may want to play in their preferred language rather than the language set by the server. DCLS gives them the option to play in any of the supported languages — translation permitting — allowing them to enjoy the game the way they want to play.

How does DCLS work

DCLS is very simple, inspired by Arma 3’s localization system.
Each resource has a string table file in the DCLS language resource. This file contains all the strings the resource displays to players, each assigned a unique localization key.
When you need to display some text, use the localize export provided by DCLS with the text’s corresponding localization key. The export will return the localized version of the text based on the player’s selected language.

Basic Guide

An in-depth guide is available in the system documentation

  1. Create a string table file in the DCLS language resource for your resource.

  2. Enter all the strings that players will see from the resource.

  3. When you need to display text to a player, use the localize export with the corresponding localization key to get the localized text.

  4. Display the localized text to the player.

Important: When sending text between two clients or the server, never assume a client’s language. Send the client the localization key for the text and allow the client to localize it locally.

Limitations

Because DCLS uses the internal game option to determine the player’s language, only the languages available in GTA V are supported.

License

GNU General Public License v3.0

8 Likes

This is cool and all but in 99% of RP servers they pick one language because its RP and if people RP in different languages then the rest of the server then no one knows whats happening or how to RP with someone they cant understand.

So I see the use for this but just dont think its really needed for RP servers as they are mainly one language so they can have a good RP experience.

King of the hill / non RP servers tho this will def help out alot tho! - So Im not saying I dont like it just saying I dont think there is a place for this in RP

I thought about that issue when I was creating it, which is why I included the bit about “preferred language” in the why use it section.

For example, if an American is playing on a Mexican server, because they’ve spent their life in an English majority culture, it would instinctively be easier for them to comprehend English over Spanish as it’s their native language. But when they need to interact with another player, they would interact in Spanish, the server’s language.

Give them the option to make it easier to play while also an understanding that the server has a specific language they need to use when interacting with others.

Although I understand that for many servers translation of custom resources isn’t really possible, which is why this is more aimed more towards resources that already have, or have the open source ability to be translated into the supported languages.

2 Likes

Do I need the source code from the scripts to implement it?

The GitHub contains the full source for the system in the language resource, as well as an example resource that uses the exports from the language resource in the language_example resource.

So how does it work? I have to implement the export in the source code of a script which should use multilanguage right?

You can either add the language resource as a dependency and provide a link to download, or copy the contents of the file directly into your resource, then create a stringtable file and add it to the resource manifest, or do what I do for my resources, and rework the system to just use a ‘stringtable.json’ file in the root directory of the resource.

As an example I’ve bundled the entire thing into a single file that I include in my resources.

I don’t understand it. Here is an example.
I have a carlock script which is in english. Now I want that the script will be multilingual so it should be on english for english people and on german for german people. So how do I use this now?
Do I have to put the export inside the carlock script or how does it work?

  1. Add the bundled file from pastebin to your resource and make sure it gets run first client side.

    • The bundled file includes a function localize(key), with a shorthand version t(key), which you can then use client side in your functions to translate a key into it’s related readable string from a pre-defined stringtable file.
  2. Create a stringtable.json file in the root directory of your resource, and add the filename ‘stringtable.json’ to the files section in your fxmanifest to ensure that the stringtable file is downloaded by clients.

    • If you look in the linked example stringtable file, there is a key STR_NUMBER_ONE, which has two translations, one for en - English, and one for de - German.
    • If you use the key STR_NUMBER_ONE in the functions mentioned above, t('STR_NUMBER_ONE') or localize('STR_NUMBER_ONE'), then they will output the translated string depending on the language the player has set their game to, defaulting to English if a translation isn’t found, and an error message if an English one isn’t found either (aka. the key doesn’t exist in the stringtable at all)
    • Add new strings to the json file like you would a normal json file, you can use the STR_LANGUAGE key as an example of all the child language keys for each supported language.
  3. Now you can use the keys you define in the json file in your functions, as an example:

    -- This will need to be in a client side file
    RegisterCommand('number', function(_, args)
        local number = tonumber(args[1])
        if number == 1 then
            print(t('STR_NUMBER_ONE'))
        else
            print('Not the right number!')
        end
    end)
    

    Rather than hard coding the string One, we call the function which selects the string from our stringtable file based on the key we’ve input and the players currently selected language.

    Now, if you run the command /number 1 you’ll see it prints One in your console, then if you change your in-game language to german and run the command /number 1 it’ll print Eins in the console instead.

    • Because the function gets the users defined language when the function is called, rather than predefined by the script, if the player changes their language while playing the game, your resource will change language as well. The only exception to this would be areas where your resource stores a string value for a long time, such as constant string in a menus or HUD.

In which resource I have to put the localice(key)? Into the carlock script or where?

The localize function is the function that translates the string, so you’d put that in the resource you are wanting to translate.