[How to] Adding "translations" to an addon

So, thought I’d make a tutorial for beginners on how to add basic translations to scripts to allow server owners to change what text is displayed to the player without having to delve into the code.

The first step to take is to create a new file that will host our text, this will be stored in key-value pairs. Now you have created the file, time to add some content. Below is an example of what the language file could look like.

LANG = {
    name = "The plugin's name",
    welcome = "Hello, %s", -- %s = player's name (e.g. havoc)
    server = "Welcome to the best server in the world!",
    given_item = "You have been given a %q" -- %q = quoted item name (e.g. "gun")
}

Since the messages are dealt with on the client, you need to make sure you send the new language file to the client with the “__resource.lua” file.

Once we’ve done that we can write our events to translate and display the messages. Below is an example of how to translate and display a chat message (Note: This is specific to the example language file above).

--[[
    indexString = the key in the language table (E.g. "name")
    colour = the chat colour in RGB (E.g. {255, 255, 255})
    args = optional table to format the string with (e.g. {"something"})
]]
AddEventHandler("translateChatMessage", function(indexString, colour, args)
    local messageString = LANG[indexString] -- Get the raw message from the language file

    local pluginName = LANG["name"] -- Not needed, this just gets the plugin's name from the language file

    if not messageString then -- We couldn't get the raw string.. It doesn't exist!
        Citizen.Trace("Error: No message string for: " .. indexString)
        return
    end

    if args ~= nil and #args ~= 0 then -- If we were passed some arguments for formatting
        messageString = string.format(messageString, table.unpack(args)) -- Format the raw string
    end
    -- messageString should now be formatted and ready to send to the client
    TriggerEvent("chatMessage", pluginName, colour, messageString)
end)

Then you can trigger the event to send a translated string. Below is some examples of how you would use this new event on the server.

-- This will display the formatted version of "Hello, %s" to the player.
-- E.g.: Hello, Havoc
TriggerClientEvent("translateChatMessage", source, "welcome", {255,255,255}, { GetPlayerName(source) })

-- This will display the "server" string to the user.
-- Since it's not got any format directives in the string, we don't need to pass the arg table
TriggerClientEvent("translateChatMessage", source, "server", {255,255,255} )

-- This will display the "given_item" string
-- E.g.: You have been given a "Gun"
TriggerClientEvent("translateChatMessage", source, "given_item", {255,255,255}, { "Gun" })

Lua’s string.format takes the same flags as printf in C++. As a result you can find most of the flags that can be used in the “raw” strings (the value inside the language file) here. The only flag that doesn’t exist is the “q” flag which does the same as “s” but, it puts quotes around the string rather than printing it as is.

This is my first tutorial so I hope I’ve written it well and you’ve understood it :slight_smile:. Feel free to ask if you want me to clarify something or if you know of a better way of doing stuff.

I hope you find this useful :smiley:

1 Like

@Havoc thanks for the tutorial, I would like to translate Mello Trainer and jobs systems, which file should I change it?

it’s .lua right?

ex. TriggerClientEvent(“jobssystem:updateJob”, source, jobName) change the “jobName” right?