Windows
Custom windows are standalone floating panels, separate from the car inspector extension points. Reached via ui.createWindow() / ui.getWindow().
identifier string Unique window identifier title string builderFunc (UIPanelBuilder) => void Called each time the window's content is (re)built Registers a custom window and returns a handle to configure and control it. The window is created resizable at 400×300 by default (300×200 minimum, 1200×800 maximum, centered) — chain WindowHandle methods to change this before calling .show(). Registering the same identifier again replaces the previous definition (a warning is logged).
Throws if builderFunc isn’t a function, or if identifier/title are empty.
var handle = ui.createWindow("my-mod-window", "My Window", buildWindow) .size(500, 400) .position(WindowPosition.center)
func buildWindow(builder) { builder.title("Hello") builder.label("This is a custom window.")}
// Later, e.g. from a command or button handler:handle.toggle()identifier string Returns a handle for an already-registered window, or null if no window (custom or built-in) with that identifier exists. Works for built-in windows too, though a handle for one supports only part of WindowHandle.
Registrations don’t survive a map/session change — a custom window must be re-created each time Main.rl runs. There’s no method to unregister a window; re-registering the same identifier is how you redefine one.
WindowHandle
Section titled “WindowHandle”Returned by createWindow()/getWindow(). Configuration methods return the same handle, so calls chain together; they only take effect the next time the window is shown, not on an already-open window (position changes never apply to an already-open window; size/resizable changes apply immediately only if the window is already resizable).
A handle for a built-in window supports only .show(), .close(), .toggle(), .isOpen(), and .identifier; the rest are for custom windows only.
Closes (hides) the window without unregistering it.
Makes the window a fixed size (not resizable), using its current size.
identifier
string The window’s identifier, read-only.
isOpen()
→ bool Returns true if the window is currently shown.
position WindowPosition Sets where the window opens — see WindowPosition.
Deprecated. Use setNeedsRebuild(), or rebuildImmediately() if you need the new content before continuing. Still works the same as rebuildImmediately(), but shows a warning in the in-game message log, once per script.
Re-invokes the window’s builder function right away to refresh its content, without changing visibility. Does nothing if the window is closed.
minWidth int e.g. 300 minHeight int e.g. 200 maxWidth int e.g. 1200 maxHeight int e.g. 800 Makes the window resizable with the given constraints. All four arguments are required — Relay registers resizable as a fixed four-argument method, so omitting any of them raises an arity error even though the constraints shown above are reasonable values to pass.
Rebuilds the window’s content once, later this frame, no matter how many times it is called before then. Does nothing if the window is closed.
title string Updates the window’s title, including on an already-open window.
Shows the window, creating it on first call.
width int height int Sets the window’s default size in pixels.
Shows the window if hidden, or closes it if shown.
WindowPosition
Section titled “WindowPosition”Passed to WindowHandle.position().
| Value | Description |
|---|---|
WindowPosition.center | Centered on screen (the default) |
WindowPosition.centerRight | Centered at 75% of screen width |
WindowPosition.lowerLeft | Anchored to the lower-left corner |
WindowPosition.lowerRight | Anchored to the lower-right corner |
WindowPosition.upperLeft | Anchored to the upper-left corner |
WindowPosition.upperRight | Anchored to the upper-right corner |
© 2026 Giraffe Lab LLC. All rights reserved.