Skip to content

Locale

Declare translations in Rust with locale!. On build, factorio-rs writes locale/<lang>/<file>.cfg into the mod output.

Keys that reference associated constants (such as Settings::CASUAL_MODE or Items::WIDGET) are checked by rustc and resolved to the Factorio name when assembling .cfg files.

factorio_rs::locale! {
file = "settings",
en {
mod_setting_name {
Settings::CASUAL_MODE = "Casual mode",
Settings::ADJACENCY_ENABLED = "Adjacency checks",
}
mod_setting_description {
Settings::CASUAL_MODE = "Relax some placement rules.",
}
"my-mod-messages" {
"hello" = "Hello engineer!",
}
}
de {
mod_setting_name {
Settings::CASUAL_MODE = "Lässig Modus",
}
}
}

Those constants may be defined in another module of the same crate. Import the type (or use a fully-qualified crate::... path) so both rustc and the frontend can resolve the key:

src/data/items.rs
use factorio_rs::prelude::*;
item! {
widget {
name = "my-mod-widget",
icon = "graphics/icon.png",
stack_size = 50,
}
}
src/data/items_locale.rs
use factorio_rs::prelude::*;
use crate::data::items::Items;
locale! {
file = "items",
en {
item_name {
Items::WIDGET = "Widget",
}
item_description {
Items::WIDGET = "A sample item.",
}
}
}

Same-module co-location still works and needs no import. Renames (use ...::Items as I + I::WIDGET) and FQ paths (crate::data::items::Items::WIDGET) are supported. String literal keys always work without imports.

For data-stage items / recipes / technologies, use item_name / item_description / recipe_name / technology_name with Items::* / Recipes::* / Technologies::*. See Prototypes and Package graphics.

  • Optional file = "..." - default file stem is locale.
  • Category idents: underscores become hyphens (mod_setting_name -> [mod-setting-name]). Quoted category strings are used as-is.
  • Keys: Type::CONST paths or string literals.
  • Values: single-line string literals only.
  • Multiple language blocks in one locale! are supported.
dist/locale/en/settings.cfg
dist/locale/de/settings.cfg
[mod-setting-name]
msr-casual-mode=Casual mode

locale! only writes .cfg files. To print a translated string in-game, pass a Factorio localised string: a plain string, or a table { "category.key", arg1, ... } where __1__, __2__, … in the locale value are filled from those args.

factorio_rs::locale! {
en {
greetings {
"hello" = "Hello, __1__!",
}
}
}
player.print(["greetings.hello", player.name()], None);
// -> player.print({ "greetings.hello", player.name })

Arrays and plain strings implement Into<LocalisedString>, so they can be passed directly to print / other localised parameters.

Example: locale_test.