F5 StudioF5 Studio
Skip to main content

Localization

F5 Board ships with 12 languages. Every player-facing string lives in locales/<code>.lua — the notifications, the placer HUD, the editor toolbar tooltips, the admin panel labels, the catalog, the modals, AND the Discord webhook embed labels.

Supported Languages

CodeLanguage
enEnglish
plPolish
deGerman
esSpanish
frFrench
ptPortuguese
nlDutch
csCzech
trTurkish
arArabic
thThai
zhChinese

Selecting a Language

config/config.lua
Config.Locale = 'pl'

Change the code and restart the resource. The change applies server-wide.

Fallback Chain

The locale lookup follows this chain:

  1. Locales[<configured locale>][key]
  2. Locales['en'][key] (fallback)
  3. The literal key name as a string (last resort)

So if you forget to translate a single key in locales/de.lua, German players see the English string for that key — not a broken [] placeholder.

The English file (locales/en.lua) is the canonical reference — it always contains every key the script uses.

What Is Localized

Over 320 keys cover:

SectionExamples
Placer HUDui_label_rotate, ui_label_depth, ui_label_place, …
Notifications — placementnotify_placed, notify_blocked, notify_limit_reached, …
Notifications — ownershipnotify_collected, notify_not_yours, notify_too_far_pickup
Notifications — editornotify_dui_not_ready, notify_note_empty, notify_image_invalid
Editor toolbartool_select, tool_note, tool_draw, …
Editor sub-toolbar labelseditor_lbl_color, editor_lbl_font, editor_lbl_size, …
Editor modalsNew / edit note, image, string
Editor tooltipsBrush style hints, color swatches, format buttons
Editor toastsUndo / redo, history actions
Target optionstarget_pickup, target_edit, target_preview, …
Modal — name / renameBoard naming, rename modal copy
Modal — public editToggle label and hint
Modal — manage editorsWhitelist labels, counters, action tooltips
Catalog (/board)Title, subtitle, counts, item-gated states
Admin panel (/badmin)Title, list, preview, owner details, confirms, toasts, map hints
Board model namesui_board_cork, ui_board_chalk, ui_board_whiteboard, …
Inventory item labelsitem_label_corkboard, item_label_chalkboard, … (ESX)
Map blip default nameblip_default_name
Discord webhook embedsTitles, field labels, value templates, footer

Adding a New Language

Translating to a language the script doesn't yet ship with takes three steps.

1. Copy en.lua and rename

cp locales/en.lua locales/ru.lua

(or whatever ISO 639-1 code you want — the script doesn't enforce a specific list, the filename just needs to be unique).

2. Change the locale key inside the file

locales/ru.lua (first line)
Locales['ru'] = {
-- ...

The Locales['<code>'] key must match what you'll put in Config.Locale. The filename itself is just convention.

3. Translate the values

Translate every right-hand-side string. Keep all %d, %s, %.1f placeholders intact — they're filled in by the script at runtime.

Example translation
-- Before
notify_limit_reached = 'Board limit reached (%d/%d)',

-- After
notify_limit_reached = 'Лимит досок достигнут (%d/%d)',

4. Activate it

config/config.lua
Config.Locale = 'ru'

Restart the resource.

Locale Key Naming Convention

The keys follow a prefix-based naming convention. Useful when you want to know which part of the UI a key belongs to without opening the script.

PrefixSection
ui_label_*Placer HUD keycaps
notify_*In-game notifications
target_*qb-target / ox_target options
tool_*Editor toolbar tool names
editor_lbl_*Editor sub-toolbar section labels
editor_note_*New / edit note modal
editor_image_*New / edit image modal
editor_string_*Edit string modal
editor_btn_*Editor modal buttons
aria_*ARIA labels for accessibility
tip_*Editor tooltips (hover hints)
tip_swatch_*Note color swatch tooltips
tip_font_*Font picker tooltips
tip_fmt_*Format button tooltips
tip_draw_*Brush style tooltips
tip_eraser_*Eraser tooltips
tip_string_*String tooltips
tip_modal_*Modal button tooltips
ui_modal_*Naming / rename / public-edit / editors modals
admin_*Admin panel
admin_tip_*Admin panel button tooltips
admin_btn_*Admin panel buttons
admin_meta_*Admin panel detail fields
admin_kbd_*Admin panel keyboard hints
toast_*Editor toast messages
label_action_*Undo/redo action labels
ui_board_*Board model display names (catalog + item)
ui_catalog_*/board catalog
item_label_*Inventory item display labels (ESX item table)
blip_default_nameDefault blip label if a board has no name
webhook_*Discord webhook embeds

Plural Forms

Three keys cover plural variants for catalog item counts (used for languages like Polish that have multiple plural forms):

locales/pl.lua (excerpt)
ui_catalog_count_one  = '%d tablica',
ui_catalog_count_few = '%d tablice',
ui_catalog_count_many = '%d tablic',

The NUI picks the right form based on the number (1 / 2-4 / 5+ in Polish; English uses _one for 1 and _many for everything else).

Customizing Without Forking

You don't need to fork a locale file to change a single string. Just edit the value in place — the file is a plain Lua table.

locales/en.lua
-- Original
notify_collected = 'Board collected',

-- Customized for your server's tone
notify_collected = "You've packed up the board",

The file is not escrow-protected — you can edit any locale freely.

Embed Localization

The Discord webhook embeds use the same locale system. So if your Config.Locale = 'pl', embeds arrive in Polish; if 'en', they arrive in English.

locales/en.lua (webhook section)
webhook_title_create        = 'Board placed',
webhook_title_rename = 'Board renamed',
webhook_title_edit = 'Board edited',
webhook_title_delete = 'Board removed',
webhook_title_delete_admin = 'Board removed by admin',

webhook_field_board = 'Board',
webhook_field_model = 'Model',
webhook_field_player = 'Player',
webhook_field_owner = 'Owner',
webhook_field_admin = 'Admin',
webhook_field_steam = 'Steam',
webhook_field_discord = 'Discord',
webhook_field_coords = 'Coords',
webhook_field_location = 'Location',

webhook_footer = 'f5_board',

If you want a different audit-channel language than the in-game one, you currently can't split them — Config.Locale drives both. Workaround: replace the webhook_* values directly with whatever language you want, regardless of which locale file is active.

Validating a Translation

After translating, restart the resource and exercise the UI. The fallback chain is silent — there is no console warning for a missing key, you simply see the English string (or the raw key name if even English is missing) in place of the missing translation.

The simplest way to verify completeness is to diff your new locale against en.lua:

diff <(grep -oE "^\s*\w+\s*=" locales/en.lua | sort -u) \
<(grep -oE "^\s*\w+\s*=" locales/ru.lua | sort -u)

The script never crashes due to a missing key — it just falls back to English.

See Also