LibLocaleOverride

A small embeddable library that lets an addon offer its own in-game language picker — so a player can read your addon in Dutch while their WoW client runs in English, without touching any other addon.

LibLocaleOverride — Per-Addon Language Override for WoW Addons

A small embeddable library that lets an addon offer its own in-game language picker — so a player can read your addon in Dutch while their WoW client runs in English, without touching any other addon. It bundles fonts for scripts WoW can't render (Thai, Indic, CJK, Hebrew, Arabic and more), supports right-to-left languages, and refreshes the UI on a switch without a /reload.

The Problem

WoW addons normally lock their language to the game client via GetLocale(). A player whose client is English can't read a supported addon in their native language, and addons can't offer languages WoW doesn't ship at all. The one existing override — the global GAME_LOCALE (and the AddonLocale addon that wraps it) — is all-or-nothing: it retargets every AceLocale addon at once, and it can't switch at runtime.

The Solution

LibLocaleOverride keeps every registered locale table and merges them on demand (an English baseline + the chosen language on top, so a partial translation still falls back cleanly) — per addon and switchable live. Picking a language for one addon never affects another. A bundled-font manager covers non-Latin scripts, and a change callback lets widgets refresh in place.

What You Get

  • Per-addon language override, switchable live. No /reload, and no effect on any addon you didn't write — GAME_LOCALE is never touched.
  • Every registered locale table is kept and merged on demand (English baseline + chosen language on top), so a partial translation falls back key-by-key instead of failing over wholesale.
  • Bundled fonts for scripts WoW can't render — Thai, Hindi/Marathi, Bengali, Punjabi, Tamil, Telugu, Hebrew, Arabic, Japanese, Korean, Chinese (Simplified & Traditional), Cyrillic and Latin. Applied per string by the script that string actually uses, so a picker listing many languages at once renders all of them — and the bundled faces carry Latin too, so English names, slash-commands and brands sitting inside translated text don't turn into boxes.
  • Right-to-left support — Hebrew and Arabic/Persian/Urdu, with contextual Arabic letter shaping and bidirectional reordering, both of which the WoW font engine does not do at all.
  • Locale-native numerals, markup-aware: digits inside colour codes, textures, atlases and hyperlinks are left alone.
  • Fonting that covers real widgets — fontstrings, whole frames recursively, buttons across every state, native Blizzard dropdown lists, and AceGUI tab strips.
  • A client-locale resolver for chat and print output, so text leaving your addon stays readable in a chat window that can't render the chosen script.
  • Optional AceGUI integration — a two-column language picker showing each language in both the current language and its own native name, and an automatic tab-font handler.
  • Offline test suite at 100% line coverage, so the per-script behaviour an English-client developer cannot see by playing is checked before it ships.

For Developers

Embed via LibStub and register your locale tables:

local LLO = LibStub("LibLocaleOverride-1.0")
LLO:RegisterLocale("MyAddon", "enUS", enUSTable, true)  -- baseline
LLO:RegisterLocale("MyAddon", "nlNL", nlNLTable)
LLO:SetStore("MyAddon", getOverrideFn, setOverrideFn)   -- your SavedVariable
LLO:ApplyStored("MyAddon")                               -- at login
local L = LLO:GetLocale("MyAddon")                       -- read L[key] at BUILD time

Add it to your addon as an external dependency — one canonical copy across your whole addon family. Read L[key] when you build a widget, never frozen at load, so a live language switch takes effect.

Then font and shape what you display:

LLO:ApplyFontToFrame("MyAddon", myWindow)   -- fontstrings + buttons, by each string's script
LLO:RegisterManagedFontString("MyAddon", fs) -- or let the library re-font it on every switch
LLO:RegisterCallback("MyAddon", RefreshUI)   -- rebuild your widgets on a switch

local line = LLO:LocalizeDigits("MyAddon", string.format(L.KILLS, n))
myText:SetText(LLO:Shape(line))              -- Shape AFTER format(), never on the template

Two guarantees worth knowing. First, fonting never resizes what it fonts: ApplyFontToFrame and ApplyFontToButton change how text renders, never a widget's size, position, anchors, parent or layout. The single exception is that a labelled button whose width isn't derived from two opposing horizontal anchors may have its width raised to fit a longer translated label — and never below the width it was built at. Give a button no label, or anchor it on both horizontal edges, to opt out entirely.

Second, Shape costs nothing on text that isn't right-to-left: a string with no Hebrew or Arabic character comes back byte-identical, so you can wrap every display string instead of branching on the active locale. It is the UI-label subset of bidirectional layout, not the full algorithm, and has one known limit: a Latin phrase that contains a bracket pair next to right-to-left text — Foo (Bar) <hebrew> — comes back with its pieces re-ordered. A lone bracketed word (<hebrew> (Beta)) is fine.

Supported clients, from one TOC: Classic Era, Anniversary / Burning Crusade, Wrath, Cataclysm, Mists of Pandaria Classic, Retail (Midnight), and World of Warcraft: Forever. On Forever and Retail, text the game keeps hidden from addons (such as some tooltip lines) is left exactly as the game drew it. The compatibility list is checked by the library's own test suite against every installed addon that depends on it, so a dependant is never held back by this library showing as out of date.

Version stamps: LibStub MINOR 18; the AceGUI, RTL and language-name satellites carry their own stamps (_aceguiMinor 4, _rtlMinor 3, _namesMinor 1) and upgrade independently, so the newest copy of each file wins regardless of load order.

Recent Updates

v0.3.6 (2026-10-17) — addons with language-aware dropdowns no longer slowly use more memory

Fixed

  • Every dropdown menu an addon asked this library to font was kept in memory for the rest of the session — together with the window it sat in — even after the addon had closed and thrown that window away. An addon that rebuilds a window with a dropdown each time you open it used a little more memory every time. Discarded dropdowns are now freed normally. Nothing about how the menus look changes.

v0.3.5 (2026-09-29) — no more errors from game tooltips on World of Warcraft: Forever and Retail

Fixed

  • On World of Warcraft: Forever and Retail, the game now hides some of its own text from addons (for example tooltip lines about what's under your mouse). When an addon asked this library to re-font a window that happened to include such text, it raised a Lua error every time. That hidden text is now left exactly as the game drew it, and everything else in the window is still fonted. Classic Era, Anniversary and Mists of Pandaria Classic do not hide text this way and behave exactly as before.

v0.3.4 (2026-09-20) — loads on World of Warcraft: Forever and on Retail 12.1

Changed

  • Marked compatible with World of Warcraft: Forever (the Classic-content beta on the modern client) and with Retail 12.1 (Midnight). Addons that require this library — FastGuildInvite and Dibs among them — were being held back on those clients because a required library the game considers out of date stops the addon itself from loading. Nothing about how languages, fonts or layout behave is different.
  • The compatibility list is now checked automatically against every installed addon that depends on this library, so it cannot quietly fall behind again.
  • The documentation for right-to-left text shaping now states its one known limit plainly: a Latin phrase containing brackets, placed next to Hebrew or Arabic text, can come out with its parts re-ordered. A lone bracketed word such as "(Beta)" is fine. This was already how it behaved; the description previously over-promised.

v0.3.3 (2026-08-25) — an Urdu text-shaping fix, a retail colour-code fix, plus internal test coverage

Fixed

  • Urdu and Arabic script: Arabic letters change shape depending on what sits next to them, and the game does none of that work — this library does it. One Urdu letter (the dotless noon ghunna) was being treated as though nothing could join onto it, which drew the following letter in its stand-alone shape instead of its joined one. Fixed, and the letter classifications are now checked against Unicode's own published data rather than inferred.
  • Retail only: coloured text using the game's newer named colour codes could come out broken when an addon displayed numbers in a language with its own numerals (Hindi, Bengali, Arabic and so on) — the colour code itself was being rewritten. Fixed. On Classic Era, Burning Crusade and Mists of Pandaria Classic nothing changes at all: those clients do not use that colour form.

Changed

  • Everything else is behind the scenes: the library now has an automated test suite covering every line of its code, run before any future change ships. Most of what this library does — Thai, Hindi, Bengali, Tamil, Telugu, Hebrew, Arabic, Korean, Japanese and Chinese rendering — can only be seen by actually switching language, so a change that broke one of them could previously reach you before anyone noticed.
  • Housekeeping: the compatibility numbers for Wrath and Cataclysm Classic were refreshed. Those clients no longer exist, so this affects nobody — it is tidied only so the list stays in step with the rest of the addon family.

v0.3.2 (2026-07-28) — updated for the latest game clients

Changed

  • Updated for Classic Era 1.15.9, Burning Crusade / Anniversary 2.5.6, and Mists of Pandaria Classic 5.5.4 — the library no longer shows as out-of-date on any of them. Retail and the older Classic versions are unaffected.
  • No other changes: nothing about how the language override, fonts or layout behave is different from v0.3.1.

Older release notes (v0.3.1 and earlier) are in the addon's full changelog.

Community

Bug reports, feature requests, or questions: Join the Discord.

License

MIT. The locale-merging core, the font routing and the BiDi/shaping logic are an original implementation. Bundled and adapted third-party assets: the public-domain LibStub; Google Noto and Sarabun fonts under the SIL Open Font License 1.1, each shipping its own OFL.txt under fonts/<Script>/; and the Arabic/Persian/Urdu base-letter to presentation-form tables, generated from the Unicode Arabic Presentation Forms via python-arabic-reshaper (MIT, © Abdullah Diab), with the reshaping/ligature approach seeded by Arabic_Reshaper_LUA by DiNaSoR (MIT).

LibLocaleOverride Team

profile avatar
  • 2
    Followers
  • 34
    Projects
  • 1.0M
    Downloads

More from PmptastyView all