Repository navigation
LuaUI CustomText
Window scripts should not hard-code the text a player reads. They pull it from the
client's language file, CustomText.bmd, so the same window shows the right language
and you can edit or translate every string in one place without touching the Lua.
This page covers the whole round trip: reading a string from a script, adding your own section, and encoding the file the client ships with.
lbl.text = Lang.GetText(Lang.TYPE.ItemBank, 16)-
Lang.TYPEis built at runtime from the sectionsCustomText.bmdactually contains, keyed by their XML node name: a<ItemBank>section becomesLang.TYPE.ItemBank. Add a section to the file and it appears here on its own - there is no list in Lua to keep in step. -
Lang.GetText(textType, id)takes one of thoseLang.TYPEvalues and the entry'sidwithin that section, and returns the string. - A missing entry never returns
nil- it comes back as the placeholder"Missing Text: <id>". Guard against it when a string may not be present yet, and fall back to an in-script default:
local function T(id, fallback)
local s = Lang.GetText(Lang.TYPE.ItemBank, id)
if s == nil or s == "" or s:match("^Missing Text: %d+$") then
return fallback
end
return s
end
lbl.text = T(16, "Zen") -- localised, English when the file has no entry 16Use Lang.GetText for text a player reads and that you want to keep in the language
file. A fixed in-script string is fine for anything else - debug labels, internal names.
The strings live in Data\Local\CustomText.xml, one section per window under the
<Language> root:
<Language Password="xxxxxxxx">
...
<CoinExchange>
<Msg ID="0" Text="Coin Exchange" />
<Msg ID="1" Text="Convert" />
<Msg ID="2" Text="Not enough WCoin." />
</CoinExchange>
</Language>- The node name is the
Lang.TYPEkey -<CoinExchange>becomesLang.TYPE.CoinExchange. Nothing in Lua or the DLL has to be told the section exists; it appears the moment the file carries it. - Each
<Msg ID="n" Text="..." />is one entry.IDis the number you pass as the second argument toLang.GetText;Textis what comes back. - Keep the
IDs stable once your window ships - the script refers to them by number, so renumbering an existing section changes what every label reads.
The client reads CustomText.bmd, not the .xml. The .xml is your editable
source; the .bmd is the packed file the client actually loads.
After editing the .xml, re-encode it with the ServerInfo (ToolKit) XML editor. It
packs the .xml into the .bmd using the Password attribute on the <Language>
root (max 8 characters). Ship the resulting .bmd, and keep the .xml as your source -
there is no tool that turns a .bmd back into .xml.
Each time you change a string:
- edit
Data\Local\CustomText.xml; - re-encode to
CustomText.bmdin the ServerInfo (ToolKit) editor; - ship the
.bmdwith the client.
Keeping the strings in CustomText.bmd instead of in the script means one place to
edit or translate them, and the same window renders in whatever language a client
runs - with no script change and no DLL rebuild.
MuLua Scripting Plugin | Home
🖼️ Lua UI
- File map
- Creating windows
- Client and server
- Designing a window
- Protocol
- Scrolling and scrollbars
- Controls
- Custom text
- Text input
- Debug console
- Bitmap Slicer
- Encrypting scripts
Maps
Monsters
Shared
Version 1.14 | 2026-09-09