Languages
The badge UI is English by default and can be switched to any language for which an overlay file is present. English is built into the firmware; every other language is a separate file you can add or remove without rebuilding.
How it works
Section titled “How it works”Every user-facing string is looked up by a key such as core.language. The
lookup has two layers:
- Built-in English fallback. The English text for every key is compiled into the firmware. Core strings live in one table; each module registers its own English table. English is always available and is the fallback whenever a translation is missing.
- Overlay files. Each non-English language is a single flat JSON file named
lang_<code>.json(for examplelang_de.json), where<code>is the lower-case language code. It is a flat object of"<key>": "<value>"pairs.
When a non-English language is active, a string is taken from the overlay if the overlay has that key, otherwise it falls back to the built-in English text. So a partial overlay simply leaves untranslated strings in English.
Where the files live
Section titled “Where the files live”Overlay files are stored on the plugins FAT partition under /plugins/i18n/.
The active language’s file is parsed into PSRAM at load time. German umlauts in
the file are written as real UTF-8 (ä ö ü Ä Ö Ü ß); the loader converts them
to the badge’s internal CP437 encoding while parsing.
The on-device picker
Section titled “The on-device picker”Open Main menu → Settings → Language. The picker is built dynamically:
- the first entry is always English (built in);
- after it comes one entry per
lang_<code>.jsonfile found in/plugins/i18n/.
Each overlay entry is labelled with that file’s own display name, read from its
core.lang_name value (the endonym). For example lang_de.json sets
"core.lang_name": "Deutsch", so it appears as “Deutsch” in the list. If a file
has no core.lang_name, its language code is shown instead.
Selecting a language applies it immediately, persists the choice, and reloads the language overlay for plugins too. With no overlay files present, only English is listed.
Adding a language
Section titled “Adding a language”Because the picker scans the directory, adding a language is just dropping a new file:
- Create
lang_<code>.jsonas a flat{ "<key>": "<value>", ... }object. - Include
core.lang_nameset to the language’s own display name, for example"core.lang_name": "Français". Without it the picker shows the bare code. - Translate the keys you want. Any key you omit falls back to English.
- Place the file in
/plugins/i18n/on the badge.
You can write the file onto the badge over the serial console with the upload
tool (upload.py --lang-overlay), or seed it into the initial plugins image at
build time (build_lang_image.py). Both are covered in
Companion tools.