Skip to content

Languages

Eleven languages ship complete — every screen, not only the buttons — in the words each language’s own iPhone uses. Anything missing from a language falls back to English string by string, so a half-finished translation shows what it has instead of breaking.

CodeLanguageCodeLanguage
enEnglishptPortuguês (Brasil)
esEspañolplPolski
frFrançaisruРусский
deDeutschtrTürkçe
itItalianoarالعربية — right to left
ja日本語
-- shared/config.lua
Config.Locale = 'en'

That is the city’s default. Each player can change it for themselves in Settings → General → Language, and their choice is remembered with the rest of their settings.

Every player reads the language they chose, on the phone and off it. The phone follows the choice in Settings, and so do the lines shown outside the phone — “No signal here.”, “Both hands are busy.”, a new application landing.

Config.Locale is the language for a player who has never chosen one, and for anything that is not said to anybody in particular.

For your own resource: LFor(source, text, ...) answers in that player’s language, and L(text, ...) in the city’s.

What follows the language besides the words

Section titled “What follows the language besides the words”
  • Dates and the clock. “Samstag, 19. September”, “9月19日土曜日”, the 24-hour clock where the language uses one. Money stays in $, the way the city counts it.
  • Arabic reads right to left. The whole screen is mirrored the way an Arabic iPhone is: rows start on the right, the back arrow points right. Two things stay as they are in every language, as they do on an iPhone — the dial pad and the calculator. Amounts, dates and numbers inside an Arabic sentence keep their order. Western digits and the Gregorian calendar, as a phone in Los Santos reads.
  • Counts. Polish, Russian and Arabic have more plural forms than one and many, so their counts read “Notatki: 4” — right for any number.

One folder, one file per language. Everything is in it: the 2,400 strings on the screen and the two dozen shown outside the phone — a notification from the city, the reason it will not open in mid-air.

locales/en.lua
locales/es.lua
locales/fr.lua
…

It is a Lua file, so the server and the client load it as the script it is, with no parsing and no conversion. The phone reads the same file and parses it, which is why the shape is strict: one ["key"] = "value", per line, and a comment is a comment. Keep to that shape and both halves see your words.

A string is its own key:

Locales['es'] = {
["Verified account"] = "Cuenta verificada",
["The last {n} hours."] = "Las últimas {n} horas.",
}

The key is the English text, so a missing translation shows English rather than a blank or a code. Braces are values the phone fills in — keep them, and put them where the sentence needs them rather than where English put them. A value left as "" means “show the English”: that is how names that never translate (Instapic, Bean Machine, Los Santos) are written.

The phone only reads the language a player picks, when they pick it — eleven dictionaries are not loaded on every start for a phone that shows one.

Open the language’s file, find the line, change the value:

["Wallet"] = "Cartera", -- the right-hand side is what the player reads

Restart the resource. Nothing else refers to it.

  1. Copy locales/en.lua to locales/<code>.lua — nl.lua, say — and change Locales['en'] to Locales['nl'].
  2. Translate the values. The keys never change.
  3. If the code is not one of the eleven, add it to the list the picker offers, in html/core/onboarding.js: const languages=[['en','English','Hello'], … ,['nl','Nederlands','Hallo']]; — the code, the name in its own language, and a greeting for the first screen.
  4. Config.Locale = 'nl', if it should be the city’s default.

The manifest already ships every file in locales/, so there is nothing to register. The picker marks a language that has no words yet as Shown in English for now rather than hiding it.