Every hook UI Extensions and HUD puts
into X4's menus. UIX ships patched copies of the vanilla menu files with callback dispatch points added, and a mod
registers a function against one by name: that is how a UI mod changes a menu without replacing the file, and how two
mods change the same menu without fighting. Read out of the mod's own .xpl files at every one of its
33 releases from 8.0.0.1 onwards, so each hook carries the release it appeared in. The current
ones are 8.0.4.10 (8.x) and 9.0.0.14 (9.x).
295 callbacks across 19 menus, 118 of which are given a return value the menu then uses. The mod's own readme says no list of them exists and to search the code, so this is that list, and the descriptions are written by hand: 13 of 295 so far.
Open a row for the registration call, what the hook is handed, what it may return and which releases have it.
uix-callbacks.lua
152 KB. This page as a Lua Language Server meta file, which is also the file it is built from: one table per menu, every callback with its contract above it. Point an editor at it as a library and a handler gets completion and signatures for what it is passed.
A callback lives on the table that dispatches it, and there are two of those: the menu, and the global
Helper. A menu is reached by the name it registers itself under, which is not its file name.
local function init()
local m = Helper.getMenu("MapMenu")
m.registerCallback("createPropertyOwned_on_start", function(config)
-- ...
end, "my_mod_id")
end
init()
The third argument is an id of your own. It is optional, and worth passing anyway: it is what
m.deregisterCallback(name, nil, "my_mod_id") needs, and registering the same name twice under one id is
ignored rather than doubled. A Helper hook is Helper.registerCallback(name, fn, id) with no
menu in front of it.
Every card below carries the exact call for that hook, with its parameters filled in.
| Kind | the return value is discarded: the hook only says that something happened and the return value is used, so what a callback returns changes what the menu does. 177 events, 118 overrides. | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Aggregation | What happens when more than one mod registers against the same hook. Nothing at the call
site announces it, and it is the field a reader cannot guess, so it is measured:
| ||||||||||||
| Registered on | dispatched off the menu table, so it is registered on that menu. dispatched off the global Helper table, so it is registered with Helper.registerCallback. dispatched off a menu handed to a Helper function, so it is registered on whichever menu is calling. | ||||||||||||
| Available | The 8.x and 9.x lines run in parallel - 8.0.4.10 and
9.0.0.14 are both current - so a card answers per line, and the row's
NEW marks the latest additions to either
(8.0.4.10 and 9.0.0.13). every 8.x release present throughout that line. 9.x from 9.0.0.4 onwards added there, and still current. never in the 8.x line a hook that line never had, so a mod using it will not run on it. 8.x up to …, gone since dropped. A hook that disappears takes every mod registered against it with it, silently: the registration still succeeds and is simply never called. The Available in filter reads the same way: each line offers what its current release has, then what every release changed. 9.0.0.13 (+17) is the seventeen hooks that release introduced, not the 293 it
carries - "present in" is true of nearly everything and so says nothing. 9.0.0.14 (0) means that
release altered UIX without adding or dropping a hook, which is most of them. | ||||||||||||
| Copying | An open card carries Copy name, Copy registration and Copy link; the last gives a URL that reopens that card. |
The version axis here is the mod's own release tags, not the game's. A UIX release usually follows a game version, but a callback appears when kuertee adds it, which is what a mod author is actually pinned to.
Nothing in UIX describes what a callback is for. The names carry a convention - [function]_[action],
with _on_ and a present-tense verb for an event - and that is the whole of what exists, which is why most
cards below say so. What descriptions there are have been written by hand into uix-callbacks.lua itself:
the file offered above is both what this page is built from and where its prose lives, so a description and the hook
it belongs to are never apart.
An entry takes three authored things, and nothing else in it is authored:
-- Menu: menu_transporter (ego_detailmonitor)
-- Menu name: TransporterMenu
-- Function: menu.display
-- Holder: menu
-- Kind: override
-- Aggregation: unanimous
-- Args: active
-- Returns: result
-- Return fields: active
-- Since: pre-8.0
-- Versions: 8.0.0.1..8.0.4.10, 9.0.0.3..9.0.0.14
-- Seen at: menu_transporter.xpl:705 (9.0.0.14)
-- Added by: kuertee
--- Decides whether the transporter room's "Go to" button is enabled.
---@param active any # what the menu decided on its own
---@return any # a table; only its `active` field is read
function menu_transporter.display_on_set_room_active(active) end
The --- lines are the description, and the text after the # on a ---@param or
---@return says what that one value is. Everything reading -- Key: value is generated from the
extraction and rewritten whenever UIX moves on, Since: included - it is measured against every release,
not remembered - while the authored kinds are carried across untouched.
The file is on
GitHub, and a description added to it is a pull request against that one file.
The Lua Language Server reads a meta file when it is listed as a workspace library. In VS Code that is
.luarc.json beside the workspace root, or the same key in settings:
{
"workspace.library": [ "path/to/uix-callbacks.lua" ]
}
The declarations exist so an editor has something to complete against and are never loaded by the game. Parameters
are typed any deliberately: what a hook is handed is a menu's own local, and naming a type it does not
have would be a guess an editor then enforces. For the wider set of X4 Lua definitions there is a packaged addon,
X4-LuaLSAddon, and for the rest of the UI namespace the
globals and
C functions references.