overlay

The native Steam-style overlay (toggled with Shift+Tab) and its element registry. Everything shown on the overlay — buttons, panels, HUDs — is an Element.

functionoverlay.add(id, spec) → Element

Registers an element under a unique string id and returns the element table (the same spec, now with .id set). Adding with an existing id replaces it.

ParamTypeNotes
idstringUnique; namespace it, e.g. "mymod.panel".
specElementSee Element.
functionoverlay.remove(id) → nil

Removes the element registered under id. Does nothing if no such element exists.

ParamTypeNotes
idstringThe element's unique id (the same string you passed to overlay.add).
functionoverlay.get(id) → Element | nil

Returns the registered element table for id. Mutating the returned table changes the element live.

ParamTypeNotes
idstringThe element's unique id.
returnsThe Element table, or nil if not found.
functionoverlay.toggle() → nil

Toggles the overlay open/closed (same as Shift+Tab). Takes no parameters.

functionoverlay.open() → nil

Opens the overlay. Takes no parameters.

functionoverlay.close() → nil

Closes the overlay (and clears any text-field focus). Takes no parameters.

functionoverlay.isOpen() → boolean

Whether the overlay is currently open. Takes no parameters. Returns a boolean.

functionoverlay.setUserMode(id, mode) → nil

Sets a user override for an element's visibility mode. Ignored for elements whose lockMode is true.

ParamTypeNotes
idstringThe element's unique id.
modestringOne of "menu", "pinned", "hud" (see Element).
functionoverlay.getUserMode(id) → string | nil

Returns the user override mode for an element.

ParamTypeNotes
idstringThe element's unique id.
returnsstring mode, or nil if none is set.
functionoverlay.focus(elemId, childIdx) → nil

Gives keyboard focus to a textbox widget. Useful right after creating an element so the user can type immediately.

ParamTypeNotes
elemIdstringThe id of the panel element that holds the textbox.
childIdxnumber1-based index of the textbox within that panel's children.
Internal: overlay._elements (id → element) and overlay._order (draw order) back the registry. Prefer add/get/remove over touching them directly.
functionoverlay.screenW() → number

Width of the window in pixels — use it to centre or right-align things. Takes no parameters.

functionoverlay.screenH() → number

Height of the window in pixels. Takes no parameters.

functionoverlay.textHeight(text, w, font) → number

How tall text will be once it is wrapped into a box w wide at size font, in pixels. This is the engine's own wrapper, not a rule that matches it — so a row laid out around the answer cannot drift from what gets drawn.

Use it to size a wrapping label, or to grow a row to fit one. A label given too little height loses its tail silently, which reads as the text simply being wrong.

local h = overlay.textHeight(s.label, 336, 14)
kids[#kids+1] = { type = "label", x = 18, y = y, w = 336, h = h, text = s.label }
y = y + math.max(46, h + 14)
functionoverlay.textLines(text, w, font) → number

The same measurement as a line count rather than a pixel height. Useful when the count itself is the decision — "does this still fit on one line?".

functionoverlay.bounds(id) → x, y, w, h

The element's position and size in pixels, with any units resolved for the window as it is now — nil if there is no such element. A paint element placed in units needs it: its self.x is the string it was written as ("5sw"), and this is the number to draw at. In the element's own pixels, the same ones paint draws in, even while it is shrunk to fit.

overlay.add("mymod.hud", { mode = "pinned", x = "2sw", y = "2sh", w = "20sw", h = "6sh",
    paint = function(d, self)
        local x, y, w, h = overlay.bounds(self.id)
        d:rect(x, y, w, h, 20, 24, 34, 220)
    end })
functionoverlay.mouseX() → number

Pointer X, or -1 until the mouse has moved once. Lets an element work out where inside itself the cursor is — which row of a list it is over, say — rather than only that it is somewhere inside. Still reported while the pointer is auto-hidden. Takes no parameters.

Asked from an element's own code — its paint, the "OverlayElement" hook, its mouse callbacks, a widget's onClick — it answers in that element's coordinates, the ones it draws in. An element shrunk to fit a small window (see Fitting the window) therefore compares the pointer against its own numbers and gets the right row. Anywhere else it is window pixels.

functionoverlay.mouseY() → number

Pointer Y, or -1 until the mouse has moved once — in the asking element's coordinates, exactly as mouseX. Takes no parameters.

One page of the MCCP modding reference. Every section is its own document; search covers all of them.